object-oriented
object-oriented thinking
Process-oriented emphasizes the steps and execution sequence of problem solving; object-oriented emphasizes the organization of data and the behavior of manipulating data into objects, and then the objects collaborate to complete tasks.
A class is an abstraction of the common characteristics and behaviors of a class of objects, and an object is a concrete instance of a class.
Object-oriented programming usually involves the following procedures:
-
Analyze objects and their relationships in your business.
-
Define classes based on common characteristics of objects.
-
Create an object and set its initial state.
-
Invoke methods on the object to complete business functions.
class definition
Classes are defined using the class keyword, and can contain member variables, constructors, and methods.
public class Person {
private String name;
private int age;
public void introduce() {
System.out.println("我叫 " + name);
}
}
member variables
Variables defined in a class but outside a method are called member variables and are often called fields or properties. Variables defined in a method, constructor, or code block are called local variables.
public class Person {
String name;
int age;
char sex;
double height;
}
Member variables can use basic types or reference types.
public class School {
String name;
String address;
}
public class Person {
String name;
School school;
}
After creating the Person object, the default value of the reference type field school is null. Before accessing school.name, you must first point it to a School object.
Person person = new Person();
person.school = new School();
person.school.name = "哈工大";
person.school.address = "南岗区";
The following code throws NullPointerException because person.school is still null.
Person person = new Person();
person.school.name = "哈工大";

When an object is no longer accessed by any valid reference, it may become a collection object for the garbage collector. The exact timing of garbage collection is determined by the JVM, and programs cannot assume that objects will be collected immediately.
Default values for member variables
When you create an object, member variables get default values.
| Type | Default Value |
|---|---|
| Integer Type | 0 |
| Floating Point Type | 0.0 |
char | \u0000 |
boolean | false |
| Reference Type | null |
There are no automatically available default values for local variables and must be assigned before reading.
The memory structure of the object
Conceptually, objects usually contain object headers, instance data, and aligned padding; array objects also require a record length.

Object headers, reference sizes, and alignment are JVM implementation details and will be affected by the JVM, compressed pointers, and running platform. Fixed bytes should not be relied on in business code.
method
Method is used to encapsulate a piece of behavior that can be repeatedly called.
访问修饰符 返回类型 方法名(参数列表) {
方法体
return 返回值;
}
return value
When the return type is not void, all execution paths that normally end must return values that are compatible with the declared type. After executing return, the current method ends immediately.
public int add(int a, int b) {
return a + b;
}
When the return type is void, there is no need to return a result, and the return early termination method without a value can also be used.
public void printPositive(int value) {
if (value <= 0) {
return;
}
System.out.println(value);
}
shape participating parameter
The parameters in a method declaration are called formal parameters, and the values passed in when the method is called are called arguments.
public boolean eat(String food) {
return "肉".equals(food);
}
boolean full = person.eat("大米饭");
When comparing string content, equals() should be used, not ==.
Calling other methods in a method
You can call methods directly between the same object, or you can use this explicitly.
public void introduce() {
System.out.println("我叫 " + name);
}
public void play() {
introduce();
// 等价于 this.introduce();
}
When calling instance methods of other classes, you need to first obtain the corresponding object.
School school = new School();
school.showInfo();
method overload
In the same class, methods with the same method name and different parameter lists constitute overloads. Different parameter lists can be reflected in different number of parameters, parameter types, or parameter orders.
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b) {
return a + b;
}
public double add(int a, double b) {
return a + b;
}Only the difference in return types cannot constitute overloading.
The compiler selects the best matching method based on the argument type. When there are multiple candidates such as basic type promotion, boxing, and variable parameters, call ambiguity may occur, so overloading design should be kept clear.
public class Calculator {
double add(double a, double b) {
return a + b;
}
int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
Calculator calculator = new Calculator();
calculator.add(10, 20); // 调用 int 版本
calculator.add('a', 'b'); // char 提升为 int
calculator.add(10L, 20L); // long 提升为 double
}
}create objects
Use the new expression to create an object and call a constructor.
Person person1 = new Person();
person1.name = "Tom";
person1.age = 20;
Person person2 = new Person();
person2.name = "Jack";
person2.age = 21;
Variables person1 and person2 hold references to two different objects.
constructor
Constructors are used to complete initialization when creating objects. The constructor name must be the same as the class name and have no return type.
public class Person {
String name;
int age;
double height;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
}If no constructors are declared in the class, the compiler provides a parameterless constructor that is related to the class access level. Once a constructor is explicitly declared, the compiler no longer automatically supplements parameterless constructors.
A class can overload a constructor with a different parameter list.
the this keyword
this represents the current object.
Access members of the current object
When member variables have the same name as local variables, use this to distinguish member variables.
public Person(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
this can be omitted when calling a method on the current object.
public void introduce() {
System.out.println("我叫 " + name);
}
public void sing() {
this.introduce();
}
Call other constructors
this() is used to call other constructors of this class and must be the first statement of the current constructor.
public Person() {
System.out.println("创建 Person 对象");
}
public Person(String name, int age) {
this();
this.name = name;
this.age = age;
}
public Person(String name, int age, double height) {
this(name, age);
this.height = height;
}Constructors cannot form circular calls between them.
package
Encapsulation is the organization of data and the behavior of manipulating data in classes and hiding implementation details that should not be directly controlled by the outside world.
attribute encapsulation
Fields are usually declared as private and controlled access is provided through methods.
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄不合法");
}
this.age = age;
}
}behavioral encapsulation
Methods should try to assume only clear and single responsibilities. High cohesion improves code readability, reusability, and testability.
Package
Packages are used to organize classes and avoid class name conflicts, and their directory structure is usually consistent with the package name.
package com.hyxy.system;
import com.hyxy.model.Student;
public class Test {
public static void main(String[] args) {
Student student = new Student();
}
}Package names are usually in lower case, and a common naming method is to reverse the company domain name and add the project name and module name. java.lang packages are automatically imported, such as String, Object and System.
Default packages are not recommended for formal projects because classes in default packages are difficult to reference and manage by code specifications in named packages.
inheritance
Subclasses inherit the parent class using extends. Inheritance is used to express the relationship that “a subclass is a parent class” and reuse the inheritable states and behaviors of a parent class.
public class Animal {
protected String name;
public void eat() {
System.out.println("动物正在进食");
}
}
public class Person extends Animal {
private String id;
public void study() {
System.out.println("学习");
}
}
Java classes only support single inheritance, but multiple levels of inheritance can be formed. Classes that do not explicitly inherit other classes will directly inherit Object by default.
Constructors are not inherited, and private members of the parent class cannot be directly accessed by subclasses, but they are still part of the parent class object state.
Access rights modifier
| modifier | Current class | Same bag class | Different bag class | Other position |
|---|---|---|---|---|
private | Yes | No | No | No |
| Default permissions | Yes | Yes | No | No |
protected | Yes | Yes | Yes | No |
public | Can | Can | Can | Can |
The access of protected in cross-package subclasses is also limited by the reference expression type. In actual use, protection methods should be preferred to encapsulate behavior.
method overrides
Subclasses re-implement instance methods that the parent class can inherit is called overriding.
public class Person extends Animal {
@Override
public void eat() {
System.out.println("这个人正在吃饭");
}
}
Rewriting needs to meet the following main rules:
- The method name and parameter list are the same.
- The return type is the same or is a subtype of the return type of the parent class.
- Subclass methods cannot have stricter access rights than parent methods.
- Subclasses cannot declare checked exceptions more broadly than parent class methods.
- The
finalmethod cannot be rewritten, theprivatemethod is invisible, and static methods are hidden rather than rewritten.
It is recommended to add @Override to let the compiler check whether the rewriting is correct.
Overwriting and dynamic binding
public class Shape {
public double area() {
return 0;
}
public static double sumArea(Shape[] shapes) {
double sum = 0;
for (Shape shape : shapes) {
sum += shape.area();
}
return sum;
}
}public class Rectangle extends Shape {
private final int length;
private final int width;
public Rectangle(int length, int width) {
this.length = length;
this.width = width;
}
@Override
public double area() {
return length * width;
}
}Shape[] shapes = {
new Rectangle(10, 20),
new Rectangle(15, 10)
};
System.out.println(Shape.sumArea(shapes));
Even if the declared type of the array element is Shape, the runtime still calls the area() method after the actual object is overridden.
super keyword
super is used to access parent class members or call parent class builders.
Call parent method
@Override
public void eat() {
super.eat();
System.out.println("这个人正在吃饭");
}
Call parent class constructor
Subclass constructors must call parent class constructors directly or indirectly. When not explicitly written, the compiler attempts to add super() on the first line.
public class Person extends Animal {
private final String id;
public Person(String name, String id) {
super(name);
this.id = id;
}
}
If the parent class does not have an accessible parameterless constructor, the subclass must explicitly call the other parent class constructor. Both super() and this() must be on the first line of the constructor, so they cannot appear directly at the same time in the same constructor.
polymorphism
References to parent class types can point to child class objects, which reflects polymorphism.
Animal animal = new Person();
Object object = new Person();
Animal[] animals = {
new Person(),
new Dog()
};
Polymorphism enables method parameters and collections to accept multiple concrete subclasses.
public void feed(Animal animal) {
animal.eat();
}
When an overridden instance method is called, the result of execution is determined by the actual object type; which members can be accessed are determined by the declared type of the reference.
Access scope for polymorphic references
A parent class reference cannot directly call a new method of a child class.



Animal animal = new Person();
animal.eat();
// animal.study(); // 编译错误
Field access does not have the same dynamic binding effect as instance methods, so it is not recommended to define fields with the same name in parent classes and subclasses.
Upward transformation and downward transformation
Converting a subclass object to its parent type is called an upward cast and can usually be done automatically.
Animal animal = new Person();
Converting a parent class reference to a child type is called a downcast, requires an explicit conversion, and the actual object must indeed belong to the target type.
Person person = (Person) animal;
person.study();
A wrong downward transition will throw ClassCastException.
instanceof operator
instanceof is used to determine whether an object can be safely converted to a specified type. When the object is null, the judgment result is false.
public void friend(Animal animal) {
if (animal instanceof Person) {
Person person = (Person) animal;
person.study();
} else if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.watchDoor();
}
}JAR package export and import
JAR is an archive file based on the ZIP format that can contain bytecode, resources, and metadata. When publishing class libraries, you usually package the compilation results into JARs, and you can also attach source code and documentation as needed.
Export in IntelliJ IDEA
-
Open
File,Project Structure,Artifacts. -
Create a new JAR Artifact and set the output content and location.
-
Build JAR through
BuildandBuild Artifacts.
Import third-party JAR
-
Create the
libdirectory in the project and copy the JAR file. -
Open
File,Project Structure,Libraries. -
Add JARs from
libto the project classpath.
Projects that use Maven or Gradle usually manage third-party libraries through dependent configurations, and manual copying of large numbers of JARs is not recommended.
Common Object Methods
toString() method
toString() returns a string representation of the object. System.out.println(object) indirectly calls the object’s toString().
The default result for Object.toString() usually contains the hexadecimal form of the class name and hash code and should not be interpreted as a reliable memory address.
public class StudentCard {
private final String id;
private final String name;
public StudentCard(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "学号:" + id + ",姓名:" + name;
}
}equals() and hashCode() methods
Object.equals() compares by default whether references point to the same object. Business objects usually override equals() based on key fields.
public class StudentCard {
private final String id;
private final String name;
public StudentCard(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof StudentCard)) {
return false;
}
StudentCard other = (StudentCard) object;
return Objects.equals(id, other.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}When rewriting equals(), reflexivity, symmetry, transitivity and consistency must be maintained, and null must be handled correctly. hashCode() should also be rewritten to ensure that equal objects have the same hash code.
String content comparison must use equals() or other explicit content comparison method.
Overview of JVM runtime data areas
JVM runtime data areas typically include the following parts:
- Program counter: Records the bytecode position currently executed by the thread, which is owned independently by each thread.
- Java virtual machine stack: Each method call creates a stack frame to hold local variables, operand stacks, return information, etc.
- Local method stack: Provides support for local method invocations. Specific implementation may be merged with the virtual machine stack.
- Heap: Mainly holds objects and arrays, is managed by the garbage collector, and is usually shared by all threads.
- Method area: Saves logical information such as class structure, runtime constant pool, and static fields; specific implementation may use mechanisms such as metaspace.
Don’t exactly equate the logical runtime area with the physical memory implementation of a JVM version.
Parameter passing in Java
Java only passes values. When a method is called, the value of the argument is copied to the formal parameter.
basic type parameter
public void modifyValue(int value) {
value++;
System.out.println("方法内部:" + value);
}
int value = 3;
modifyValue(value);
System.out.println("方法外部:" + value);
What is modified internally within the method is a copy of the formal parameters and does not change external variables.

Reference type parameter
When you pass an object, you copy the reference value. Formal parameters and arguments initially point to the same object, so by modifying object properties, the caller can see the change.
public void rename(Person person) {
person.name = "李四";
}
Person person = new Person();
person.name = "张三";
rename(person);
System.out.println(person.name); // 李四
But reassigning a formal parameter to null or another object will only change the reference copy held by the formal parameter.
public void clearReference(Person person) {
person = null;
}
After the call, the external variable still points to the original object.
Modify array content
If the goal of the method is to empty the original array, modify the array elements rather than just having formal parameters point to the new array.
public void clear(int[] array) {
Arrays.fill(array, 0);
}
If a method is creating and returning a new array, the return value should be received by the caller.
public int[] createEmptyCopy(int[] array) {
return new int[array.length];
}
If you enjoyed this, leave a comment~