java面向对象四大特性是封装、继承、多态和抽象,封装通过访问控制隔离细节并降低耦合,继承在满足“is-a”关系时复用行为,多态依赖jvm虚方法表实现运行时动态分派,抽象则按契约粒度选择接口或抽象类以保障可维护性与可演进性。

Java 面向对象(OOP)是大厂面试必考基础,答得好不靠死记硬背,而在于讲清概念背后的逻辑、设计意图和真实场景中的取舍。关键不是罗列“四大特征”,而是让面试官看到你真正用过、想过、调优过。
封装:别只说“private + getter/setter”
封装的本质是控制访问边界、降低模块耦合。面试时如果只提加 private 和写 set/get,容易被追问:“那为什么 Lombok 的 @Data 不破坏封装?什么时候该暴露 setter?”
- 重点讲清楚“谁需要改、谁只需要读”——比如订单状态用 enum + private status + changeToShipped() 方法,比开放 setStatus() 更安全
- 指出“封装≠全藏起来”,像 StringBuilder 的 value 字段虽是 package-private,但这是为性能妥协的合理设计
- 可以补充:Spring Bean 的属性注入(@Autowired)绕过构造器,其实是对封装的弱化,所以推荐构造器注入
继承 vs 组合:别再说“能用组合就不用继承”
这句话没错,但面试官想听你判断“什么时候真该用继承”。关键看是否满足“is-a”且行为可自然复用。
- 反例:User 和 Admin 用继承——Admin 不是 User 的子类型(权限逻辑独立),更适合组合 + 策略模式
- 正例:ArrayList 和 Vector 都是 List 实现,但 Vector 已废弃;更典型的是 AbstractList 提供通用遍历逻辑,子类专注 size()/get() 实现
- 提醒:Java 单继承限制下,接口 default 方法 + 组合才是现代主流解法(如 Collections.synchronizedList() 返回包装类)
多态:从编译期到运行期,讲清 JVM 怎么选方法
光说“父类引用指向子类对象”太浅。面试常考 invokevirtual 指令、虚方法表(vtable)、以及重载(overload)和重写(override)的根本区别。
- 重载在编译期决定,靠参数类型静态匹配;重写在运行期决定,靠实际对象类型查 vtable
- 举例:map.put(null, "a") 调用的是 HashMap 的 put(K,V),但若传入 LinkedHashMap,执行的仍是其重写的 put(可能触发 afterNodeInsert)
- 注意陷阱:static 方法、final 方法、private 方法不参与多态;Lambda 表达式本质是函数式接口的实例,也走多态流程
抽象与接口:Java 8/9/17 后该怎么选?
别再背“接口定义行为,抽象类定义模板”。现在接口能有 default/static 方法,抽象类也能空实现——区别在于设计契约的粒度和演化成本。
- 优先接口:当你定义“能力”(如 Comparable、Closeable),且希望多个无关类都能实现
- 选抽象类:当需要共享代码(如 AbstractMap 提供 keySet()/entrySet() 基础实现)或强制子类初始化流程(构造器链)
- Java 17 密封类(sealed)出现后,某些场景下用 sealed class + permits 替代接口+实现类,能更好控制继承范围
不复杂但容易忽略:所有 OOP 特性最终都服务于“可维护性”和“可演进性”。面试时哪怕例子简单,只要能说出“这里为了以后加日志方便”“这里防止并发修改”“这里预留扩展点”,就比背书强得多。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











