同叫【类】,Java 没有多继承、Python 靠下划线约定、C++ 没有垃圾回收——学 OOP 和学某门语言的 OOP 是两件事。
4.1 讲了三种结构的骨架,这一节先说清骨架和语法之间的那条线。
一、各家给的家伙什不一样
最容易踩的四样:多继承、接口、可见性、垃圾回收。
Java:不支持多继承、有 interface、三档可见性关键字、有垃圾回收。
Python:支持多继承、没有接口关键字(靠约定)、可见性靠下划线、引用计数+分代。
C++:支持多继承、接口用纯虚类、三档可见性、没有垃圾回收(靠 RAII)。
二、多继承的实测
class C(A, B): pass——两个父类都写了 who,会找到哪一个?
实测 C().who() 返回 A,C.__mro__ 是 C → A → B → object。
A 排在前面,所以先找到 A.who。这就是方法解析顺序。
2.4 讲过 MRO 顺着链往上找,这里看到的是它遇到分叉时的规矩:按声明顺序。
三、Java 为什么不要多继承
为了避开这套顺序带来的歧义。C++ 里有名的菱形继承问题,就是它躲开的那件事。
它用 interface 换个方式表达【一个类可以有多个能力】——能力可以多,实现只能一份。
C++ 要它,是因为它要极致控制;Java 不要,是因为它要确定性。两种取舍都合理。
四、读书的方法
本书讲的是共同的骨架:类是汇总+隐藏+创建很多个,多态是调用端公用化,继承是共享一份代码。 具体语法各语言自己查——查的时候你会很快,因为骨架已经懂了。 遇到【书上说支持、你的语言不支持】不要慌:那是实现差异,不是概念差异。
五、动手 Demo:OOP 的结构会根据编程语言的不同而略有差异
把 Java/Python/C++ 的四样能力并排放。 再实测 Python 的多继承:两个父类同名方法,到底找哪一个。
class A:
def who(self): return "A"
class B:
def who(self): return "B"
class C(A, B):
pass
print(C().who())
print([x.__name__ for x in C.__mro__])
实跑输出:
--------------------------------------------------------------------
OOP 的结构会根据编程语言的不同而略有差异
--------------------------------------------------------------------
同样是【类】,各家给的家伙什不一样。**最容易踩的是这一条:**
能力 Java Python C++
--------------------------------------------------------------
多继承 不支持 支持 支持
接口 interface 没关键字,靠约定 纯虚类
可见性 三档关键字 靠下划线约定 三档关键字
垃圾回收 有 引用计数+分代 没有(RAII)
实测 Python 的多继承——它真的会去两条线上找方法:
class C(A, B): pass
C().who() → A
C.__mro__ → C → A → B → object
**`A` 排在前面,所以先找到 `A.who`。**这叫方法解析顺序。
Java 不支持多继承,**正是为了避开这套顺序带来的歧义**——
它用 `interface` 换个方式表达【多个能力】。
**所以【学 OOP】和【学某门语言的 OOP】是两件事。**
本书讲的是**共同的骨架**,具体语法各语言自己查。
实测:C().who() 返回 A,MRO 是 C → A → B → object。
A 排在前面,所以先找到 A.who——Java 不支持多继承,正是为了避开这套顺序带来的歧义。
30 秒实验
- 在你用的语言里试一次多继承(或接口多实现),看同名方法解析到哪一个。
- 把四样能力按你的语言填一遍,标出【不支持】的那几格。
常见误区
- 以为书上写的每一条你的语言都有。四大能力各家差别很大。
- 以为语法不一样就是概念不一样。骨架是共通的,语法各自不同。
自测三问(点开对答案)
1. 四样最容易踩的语言差异是什么? —— 多继承、接口、可见性、垃圾回收。 2. Python 多继承时同名方法找哪一个? —— 按 MRO 顺序找:`class C(A, B)` 时是 C → A → B → object,所以找到 A 的。 3. Java 为什么不要多继承? —— 为了避开方法解析顺序带来的歧义;它用 interface 表达多个能力——能力可多,实现只有一份。- ☐ 下一节(4.3 三大要素之一:具有三种功能的类)
相关笔记
- 继承对共同点和不同点进行系统的分类和整理 — MRO 的来历
- OOP具有结构化语言所没有的三种结构 — 骨架在哪
- ☕ Java基础 · 索引 — 一门不支持多继承的语言
- 🧩 面向对象是怎样工作的 · 索引