Java面向对象仅有封装、继承、多态三大核心特性;抽象是思维方法而非独立机制;接口等属工具延伸。封装强调有意识暴露最小接口,绑定状态与行为,并辅以getter/setter及构造器校验。

Java 的面向对象(OOP)没有“五大特性”这一官方定义——这是常见误解。Java 官方文档和《Java Language Specification》只明确支持封装、继承、多态这三大核心特性;而“抽象”是支撑前三个的思维方法,并非独立运行时机制;“接口”或“类设计原则”常被误列为第五项,实为工具或实践延伸。
封装:控制访问 + 隐藏实现细节
封装不是简单加 private,而是有意识地暴露最小必要接口,把状态与行为绑定在类内管理。
-
private字段必须配publicgetter/setter(或更严格的逻辑校验),否则字段不可达也无意义 - 构造器里做参数校验(如
if (age ),比放任setAge(-5)后再出错更安全 - 避免返回可变对象引用:不要直接
return this.dates;,应return new ArrayList(this.dates);或用Collections.unmodifiableList()
继承:extends 是 is-a 关系,不是代码复用捷径
Java 只支持单继承,extends 表示严格意义上的“子类是父类的一种”,语义错误比编译失败更危险。
- 别为了复用方法强行继承:比如
Car extends Engine违反常识,应改为组合(Car持有Engine引用) -
protected成员虽可被子类访问,但破坏封装边界;优先用final方法 + 模板方法模式控制扩展点 -
super()调用必须是子类构造器第一行,否则编译报错Implicit super constructor ... is undefined
多态:靠 override 和动态绑定,不是重载(overload)
只有运行时根据实际对象类型调用对应方法,才算多态;方法重载(同名不同参)在编译期就决定了,不属于多态范畴。
立即学习“Java免费学习笔记(深入)”;
- 确认重写成功:务必加
@Override注解,否则拼错方法名(如toString()写成toStirng())不会报错,但失去多态效果 - 静态方法不能被重写:声明类型决定调用哪个
static方法,跟实际对象无关 - 成员变量不具多态性:子类定义同名字段只会隐藏(shadow)父类字段,而非覆盖
抽象:靠 abstract 类和 interface 实现,但本质是建模手段
抽象不是语法糖,是把共性提炼成契约的过程。Java 8+ 后 interface 可含 default 和 static 方法,但它仍代表“能做什么”,而非“如何做”。
-
abstract类适合有部分共通实现(如模板方法),interface更适合定义能力契约(如Comparable、Runnable) - 从 Java 9 开始,
private方法可在interface中定义,用于default方法间逻辑复用,但不能被实现类继承 - 不要为抽象而抽象:一个
abstract class Animal若只有abstract void sound();,不如直接用interface
真正容易被忽略的是:OOP 特性之间存在张力。比如过度封装会阻碍测试(私有方法难测),滥用继承会破坏开闭原则,强推多态可能引入不必要的抽象层。写 Java 不是凑齐五个关键词,而是判断哪个机制最贴合当前问题的语义和演化需求。










