Untitled
# Paradigms
- There are many paradigms
- Different languages support different paradigms
- In OOSD, everything is based on the concept of
Object - Objects are units that contain
- Data (State)
- Methods (Behavior) (operation on the date)
- Object-oriented:
- Complex
- data and behavior are in a single object
- Functional: keep them separate
- That is, it depends
- It depends on the problem one is trying to solve
- No paradigm works best in all situations
- No such a thing as
one size fits all
# Benefits of OOSD
- Modular
- Reduced complexity
- Easier maintenance
- Code reuse
- Faster development
# Classes
Class
- A blueprint/template for creating objects
Object
- An instance of a class
Methods can change the value of fields
Different car instances have different states
- They are independent objects stored in different locations of memory
Example: create the TextBox class
public class TextBox {
// declare field
// should initialize the field to avoid null pointer exception
public String text = "";
public void setText(String text) {
this.text = text;
}
public void clear() {
// don't need to use 'this'
text = "";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- Example: create TextBox objects
public class Main {
public static void main(String[] args) {
// use 'var' to replace 'TextBox'
var textBox1 = new TextBox();
textBox1.setText("Box 1");
System.out.println(textBox1.text.toLowerCase());
// they are completely independent of each other
var textBox2 = new TextBox();
textBox2.setText("Box 2");
System.out.println(textBox2.text.toUpperCase());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Memory Allocation
- Heap store objects
- Stack store primitives short-lived variables (store references to objects on the heap)
public class Main {
public static void main(String[] args) {
// the newly created object is stored on the heap;
// the address of the text object is stored on the stack; so 'textBox1' is a reference type
var textBox1 = new TextBox();
var textBox2 = textBox1; // reference the same TextBox object
textBox2.setText("Box 2");
System.out.println(textBox1.text); // get "Box 2"
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- All memory on the stack will be immediately removed after finishing executing the main function
- That is, memory deallocation is automatically handled by Java
- Garbage collector will remove unused objects on the heap
# Encapsulation
- Bundle the data and methods that operate on the data in a single unit
- By clicking the lightbulb, IntelliJ can help to create getters and setters
# Abstraction
- Reduce complexity by hiding unnecessary details
- Hide the implementation details of a class and treat it as a black box
- Have a simple interface to work with
# Coupling
- The level of dependency among classes
- The more classes are coupled to each other, the more costly our changes are going to be
- By reducing the coupling, we can reduce the impact of changes
- Reduce coupling points by reducing the number of unnecessary getter & setter functions
public class Browser {
// only navigate is public
public void navigate(String address) {
String ip = findIpAddress(address);
String html = sendHttpRequest(ip);
System.out.println(html);
}
// hide from other classes, only used internally
private String sendHttpRequest(String ip) {
return "<html></html>";
}
// hide from other classes, only used internally
private String findIpAddress(String address) {
return "127.0.0.1";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- By abstracting away complex internal implementation, we have reduced coupling among classes
# Constructor
- This is wrong:
- All necessary parameters should be set when creating the object
// A Constructor method
public Employee(int baseSalary, int hourlyRate) {
setBaseSalary(baseSalary); // data validation
setHourlyRate(hourlyRate); // data validation
numberOfEmployees++;
}
// In so doing, the main class looks like this:
public static void main (String[] args) {
var employee = new Employee(50_000, 20);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Method Overloading
public int calculateWage(int extraHours) {
return baseSalary + (getHourlyRate() * extraHours);
}
public double calculateWage(double extraHours) {
return baseSalary + (getHourlyRate() * extraHours);
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# Constructor Overloading
public Employee(int baseSalary) {
// reference to the method down below
this(baseSalary, 0);
}
public Employee(int baseSalary, int hourlyRate) {
setBaseSalary(baseSalary);
setHourlyRate(hourlyRate);
numberOfEmployees++;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- Use
Command + Pto see different constructors
# Static Members
- A class can have two types of members
- Instance members
- Belong to instances or objects
- Instance members like variables can be accessed by using dot operator
- Static members (Class members)
- The fields and methods that belong to a class, not an object
- Static methods can only use static variables
- It cannot use instance members because they belong to instances
- Independent of objects
- Cannot be accessed by using dot operator on an object
- Represent a concept that should be in a single place
- This concept does not belong to any individual employee
- The main method is static because Java runtime is able to directly call this method without having to create a new object
- Therefore, if a class is not expected used as a blueprint to create multiple instances, it should be static
- The fields and methods that belong to a class, not an object
- Instance members
// Instance Variable
var employee = new Employee();
employee.name = "Scott";
// Static Variable
employee.numberOfEmployees = 100; // ❌ doesn't work, inaccessible
System.out.println(Employee.numberOfEmployees); // ✅ works
1
2
3
4
5
6
7
2
3
4
5
6
7
# Q & A
- What is the difference between a class and an object?
- A class is a blueprint or template for creating objects.
- An object is an instance of a class.
- What does instantiating mean?
- Instantiating means creating an instance of a class: new Customer()
- What is the difference between stack and heap memory? How are they managed?
- Stack is used for storing primitive types (numbers, boolean and character) and variables that store references to objects in the heap.
- Variables stored in the stack are immediately cleared when they go out of scope (eg when a method finishes execution).
- Objects stored in the heap get removed later on when they’re no longer references. This is done by Java’s garbage collector.
- What are the problems of procedural code? How does object-oriented programming help solve these problems?
- Big classes with several unrelated methods focusing on different concerns and responsibilities.
- These methods often have several parameters.
- You often see the same group of parameters repeated across these methods.
- All you see is procedures calling each other passing arguments around.
- ==
- By applying object-oriented programming techniques, we extract these repetitive parameters and declare them as fields in our classes.
- Our classes will then encapsulate both the data and the operations on the data (methods).
- As a result, our methods will have fewer parameters and our code will be cleaner and more reusable.
- What is encapsulation?
- Encapsulation is the first principle of object-oriented programming.
- It suggests that we should bundle the data and operations on the data inside a single unit (class).
- Why should we declare fields as private?
- How we store data in an object is considered an implementation detail.
- We may change how we store the data internally.
- Plus, we don’t want our objects to go into a bad state (hold bad data).
- That’s why we should declare fields as private and provide getters and or setters only if required.
- These setters can ensure our objects don’t go into a bad state by validating the values that are passed to them.
- What is abstraction?
- Abstraction is the second principle of object-oriented programming.
- It suggests that we should reduce complexity by hiding the unnecessary implementation details.
- As a metaphor, think of the remote control of your TV. All the complexity inside the remote control is hidden from you. It’s abstracted away. You just work with a simple interface to control your TV. We want our objects to be like our remote controls.
- What is coupling?
- Coupling represents the level of dependency between software entities (eg classes).
- The more our classes are dependent on each other, the harder it is to change them.
- Changing one class may result in several cascading and breaking changes.
- How does the abstraction principle help reduce coupling?
- By hiding the implementation details, we prevent other classes from getting affected when we change these details.
- For example, if the logic board and transistors inside a remote control change from one model to another, we’re not affected. We still use the same interface to work with our TV.
- Also, reducing these details and exposing fewer methods makes our classes easier to use.
- For example, remote controls with fewer buttons are easier to use.
- What are constructors?
- Constructors are called when we instantiate our class.
- We use them to initialize our objects.
- Initialization means putting an object into an early or initial state (eg giving it initial values).
- What is method overloading?
- Method overloading means declaring a method with the same name but with different signatures.
- The number, type and order of its parameters will be different.
- What are static methods?
- Static methods are accessible via classes, not objects.
上次更新: 2021/12/31, 15:34:56