Java SE 面向对象(OOP)核心知识点详解
(从零基础到面试/项目常用级别 · 2026 年视角 · 清晰 + 对比 + 代码 + 常见误区)
Java 是纯面向对象语言(几乎一切皆对象),它的面向对象特性比 C++ 更纯粹、更严格。下面按实际掌握顺序和重要程度排列。
一、面向对象四大基本特征(必须倒背如流)
| 特征 | 中文名 | 一句话核心含义 | Java 中的体现方式 | 面试经典问题 |
|---|---|---|---|---|
| 封装 | Encapsulation | 把数据和操作数据的方法绑定在一起,对外隐藏细节 | private 成员变量 + public/getter/setter | 为什么 getter/setter 比直接 public 好? |
| 继承 | Inheritance | 子类复用父类的属性和方法 | extends(单继承) | Java 为什么不支持多继承?用接口解决什么? |
| 多态 | Polymorphism | 同一个方法调用,不同对象有不同表现 | 方法重写 + 父类引用指向子类对象 | 编译时绑定 vs 运行时绑定? |
| 抽象 | Abstraction | 隐藏具体实现,只暴露必要接口 | abstract 类 / 接口 | abstract class 和 interface 区别? |
二、类与对象(最基础但最容易写错)
// 类(模板 / 蓝图)
public class Person {
// 成员变量(属性 / 字段)
private String name; // 封装:private
private int age;
private static int count; // 类变量(static)
// 构造方法(创建对象时调用)
public Person() { // 无参构造(默认提供,但写了有参就没了)
this("未知", 0); // 调用其他构造
}
public Person(String name, int age) {
this.name = name;
this.age = age;
count++;
}
// 方法(行为)
public void eat() {
System.out.println(name + " 在吃饭");
}
// getter / setter(封装的体现)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// 静态方法
public static int getCount() { return count; }
}
使用:
Person p1 = new Person("张三", 25);
Person p2 = new Person();
p1.eat(); // 张三 在吃饭
System.out.println(Person.getCount()); // 2
三、this 与 super 的使用场景(高频易错)
| 关键字 | 代表什么 | 常见用法场景 | 不能用在哪 |
|---|---|---|---|
| this | 当前对象本身 | 区分同名变量、调用其他构造、返回自身 | static 方法里 |
| super | 父类对象(父类的引用) | 调用父类构造、调用父类方法/属性 | static 方法里 |
class Student extends Person {
private String school;
public Student(String name, int age, String school) {
super(name, age); // 必须是第一行
this.school = school;
}
@Override
public void eat() {
super.eat(); // 调用父类的 eat
System.out.println("学生在食堂吃饭");
}
public Student chain() {
this.age = 18;
return this; // 方法链调用
}
}
四、方法重载(Overload) vs 方法重写(Override)
| 维度 | 方法重载(Overload) | 方法重写(Override) |
|---|---|---|
| 发生位置 | 同一个类 | 子类与父类 |
| 方法名 | 相同 | 相同 |
| 参数列表 | 不同(个数/类型/顺序) | 必须完全相同(包括泛型在 JDK 1.5 后) |
| 返回值类型 | 可以不同(但建议一致) | 必须相同或协变返回类型(子类更小范围) |
| 访问修饰符 | 无要求 | 不能更严格(public > protected > 默认 > private) |
| 异常 | 无要求 | 不能抛出更广的 checked 异常 |
| 注解 | 无需 | 推荐加 @Override(编译检查) |
五、访问权限修饰符对比(最容易混)
| 修饰符 | 本类 | 同包 | 子类(不同包) | 其他类(不同包) | 记住口诀 |
|---|---|---|---|---|---|
| public | √ | √ | √ | √ | 全公开 |
| protected | √ | √ | √ | × | 包 + 子类 |
| 默认(无) | √ | √ | × | × | 包内可见 |
| private | √ | × | × | × | 只有自己能用 |
六、抽象类 vs 接口(2026 年面试最爱问的区别)
| 维度 | abstract class | interface(JDK 8+) |
|---|---|---|
| 成员变量 | 可以有普通变量 + 常量 | 只能有 public static final 常量 |
| 方法 | 可以有抽象方法 + 具体方法 | 可以有抽象方法 + default 方法 + static 方法 |
| 构造方法 | 可以有 | 不能有 |
| 继承/实现 | 单继承(extends) | 多实现(implements) |
| 访问修饰符 | 可以是任意 | 默认 public |
| 适用场景 | 有部分相同实现,想强制子类实现某些方法 | 完全定义规范 / 行为契约,多实现场景 |
JDK 8+ 接口新特性(必须知道):
- default 方法:提供默认实现(解决接口演进问题)
- static 方法:工具方法
- private 方法(JDK 9+):接口内部复用逻辑
interface Flyable {
int MAX_SPEED = 1000; // public static final
void fly(); // 抽象方法
default void land() { // 默认方法
System.out.println("慢慢降落...");
}
static void repair() { // 静态方法
System.out.println("飞机维修中");
}
}
七、final 关键字在面向对象中的三种用法
- final 变量:常量(基本类型值不可改,引用类型地址不可改)
- final 方法:不能被子类重写
- final 类:不能被继承(String、Integer、LocalDateTime 等)
八、面向对象设计原则(SOLID)速记(中高级必备)
- Single Responsibility Principle → 单一职责
- Open-Closed Principle → 对扩展开放,对修改关闭
- Liskov Substitution Principle → 里氏替换原则(子类可替换父类)
- Interface Segregation Principle → 接口隔离
- Dependency Inversion Principle → 依赖倒置(面向接口编程)
九、常见误区 & 面试追问
- static 方法能被 override 吗? → 不能,只能被 hide(隐藏)
- 子类构造方法第一行不写 super() 会怎样? → 编译器自动调用父类无参构造(没有就报错)
- private 方法能被继承吗? → 不能被继承,但子类可以定义同名方法(不是重写)
- 接口可以有构造方法吗? → 不能
- 为什么 Java 不支持多继承? → 菱形问题,用接口 + default 方法解决
你现在最想深入的面向对象部分是哪一块?
- 构造方法 / this / super 的各种细节?
- 多态的实现原理(虚方法表)?
- 抽象类 vs 接口的真实项目选型?
- final / static / this 的组合使用?
- 还是想看一个完整的面向对象小项目示例?
直接告诉我,我继续给你针对性内容~