🧩 第四章 面向对象编程技术:去除冗余、进行整理
📄 一句话概括

同叫【类】,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. 把四样能力按你的语言填一遍,标出【不支持】的那几格。

常见误区

  1. 以为书上写的每一条你的语言都有。四大能力各家差别很大。
  2. 以为语法不一样就是概念不一样。骨架是共通的,语法各自不同。
自测三问(点开对答案) 1. 四样最容易踩的语言差异是什么? —— 多继承、接口、可见性、垃圾回收。 2. Python 多继承时同名方法找哪一个? —— 按 MRO 顺序找:`class C(A, B)` 时是 C → A → B → object,所以找到 A 的。 3. Java 为什么不要多继承? —— 为了避开方法解析顺序带来的歧义;它用 interface 表达多个能力——能力可多,实现只有一份。

相关笔记