概述

面向对象的三个基本特征是:封装、继承、多态。

封装

封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承

面向对象编程 (OOP) 语言的一个主要功能就是”继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

多态

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
实现多态,有二种方式,覆盖,重载。

三大特征的定义齐备,但定义回答不了两个真问题:每个特征解决什么工程问题(动机),以及它们在 Java 中的落地机制与代价。本文按”动机 → 机制 → 代价 → 设计准则”重讲三特征,并补上常被遗漏的第四特征”抽象”。

封装:把变化关进笼子

动机:模块的使用者不应依赖其内部实现,否则实现一改、调用方全崩。封装把”稳定的接口”与”易变的实现”隔开,修改的影响面被限制在类内部。

Java 机制:访问修饰符(private/protected/public/包级)、getter/setter(可控校验而非裸字段)、不可变对象(final 字段+无 setter,封装的极致形态)。

代价与准则:

  • 过度封装(每个字段 getter/setter 全开)等于没封装——暴露面最小化:能 private 不 protected,能包级不 public
  • 封装的单位是”职责”而非”类”:一个类封装一个变化原因(与单一职责原则同源)
  • 破坏封装的信号:外部频繁 instanceOf+强转访问子类细节、反射改私有字段成常态

继承:复用是把双刃剑

动机:is-a 关系的代码复用——子类免费获得父类实现,扩展点通过覆写注入。

Java 机制:单继承(类)+ 多实现(接口);super 调用链;构造器不继承但首行隐式/显式调用父构造。

代价(为什么现代设计”组合优于继承”):

  • 脆弱基类问题:父类内部修改可能破坏子类(子类依赖了父类实现细节)
  • 破坏封装:继承让子类窥见父类 protected 内部,父子强耦合
  • 层次爆炸:多维度变化用继承表达会产生类组合矩阵(咖啡+奶+糖式继承树)
  • 运行时不可变:继承关系编译期固定,组合可运行时替换

准则:继承只用于稳定的 is-a 层次+模板方法骨架(如 AbstractList);行为复用优先组合/委托;扩展点优先接口+默认方法。

多态:同一调用、不同行为

动机:调用方依赖抽象而非具体类,新增实现不改调用代码(开闭原则的执行机制)。

Java 机制分两层:

  • 编译期多态(重载 overload):同名方法不同参数签名,编译期按静态类型选方法——严格说是”名字复用”,与运行时多态机制不同
  • 运行时多态(覆写 override + 动态绑定):变量声明类型为父类/接口、实际对象为子类时,invokevirtual 按实际类型查虚方法表(vtable)分派——“父引用调子实现”的物理基础
List<String> a = new ArrayList<>();   // 声明类型 List,实际 ArrayList
a.add("x"); // invokevirtual → ArrayList.add

三要素记忆:继承/实现关系、方法覆写、父引用指向子对象;缺其一即无运行时多态。

多态的设计价值:策略模式/模板方法/依赖注入全部建立在”面向抽象编程+运行时绑定”之上——Spring 注入接口、运行期换实现,就是多态在框架级的应用。

第四特征:抽象(常被遗漏)

抽象是前三者的前提:先识别”什么是不变的本质”(抽象),才能封装变化、继承共性、多态替换。Java 载体是抽象类与接口;设计层面的抽象能力(命名概念、划边界)比语法更难也更值钱——DDD 的领域建模本质就是抽象活动。

四特征的协作范式

  • 抽象定边界(接口/抽象类表达概念)
  • 封装护实现(变化关进类内)
  • 继承建骨架(模板方法复用流程)
  • 多态供替换(面向抽象注入实现)

JDK 集合框架是四特征合体的范本:Collection/List 抽象契约、AbstractList 封装骨架与继承复用、ArrayList/LinkedList 多态替换、各自封装内部数据结构。

面向对象的特征不是四个名词,而是一套控制变化影响面的协作机制:封装限制变化的可见范围,继承与多态让扩展不改旧代码,抽象决定这一切的边界画在哪。按动机理解特征,设计原则(SOLID)就都是它们的自然推论。