🧩 第八章 UML:查看无形软件的工具
📄 一句话概括

继承树就是集合包含——实测 issubclass 矩阵里 True 有 6 格(含自身),每个类只写自己新增的属性(1/1/2),共有部分全压在祖先里。

📝 本节和前面几节的关系

8.7 画了概念类,这一节回答这些类之间怎么连。答案是第七章的老话:继承就是子集。

一、用集合的语言说继承

父类 = 全集,子类 = 子集,issubclass(子, 父) 就是【子集】这个判断。 交集是子类们共有的能力,差集是父类独有、子类没有的那部分。 7.2 已经用 set 验证过;这里换成类来验证同一件事。

二、实测:6 格 True

三个类 Item → Book → EBook 两两判定,True 共 6 格(含对角线)。 对角线全 True:每个类都是自己的子集——这就是为什么继承关系是【自反】的。 True 的分布是个三角形(左下角连成一片),这个形状就是继承树本身。

三、每个类只写新增的属性

实测自己新增的属性:Item 1 个、Book 1 个、EBook 2 个。 共有的那个 code 只在 Item 里写一次,子类格子里不重复。 如果每个类都重抄一遍,图上会显得平均,但改的时候要改三处——这正是 4.9 说的重复定义。

四、线怎么画

实线+空心三角,三角指向父类,从子类往上画。 箭头方向别画反:反了就读成【父类是一种子类】,逻辑全错。 多个父类(多继承)就从子类拉出多条线,Java 不支持,Python 支持但要查 MRO。

五、动手 Demo:使用类图表示根据集合论进行整理的结果

定义三个有继承关系的类,两两做 issubclass 判定。 输出矩阵,并数每个类自己新增的属性。

class Item(object):
    code: str = ""

class Book(Item):
    title: str = ""

class EBook(Book):
    size: int = 0
    fmt: str = "pdf"

cs = [Item, Book, EBook]
for a in cs:
    print([issubclass(a, b) for b in cs])
# [True, False, False] / [True, True, False] / [True, True, True]
print(sum(issubclass(a, b) for a in cs for b in cs))   # 6

实跑输出:

--------------------------------------------------------------------
使用类图表示根据集合论进行整理的结果
--------------------------------------------------------------------

  继承树就是集合的包含关系——**可以用 `issubclass` 逐对判定**。实测:

  两两判定矩阵(True = 左边是右边的子集,即继承关系成立):

  被判定类     Item     Book      EBook
  --------------------------------------
  Item         True     False     False
  Book         True     True      False
  EBook        True     True      True

      各类自己新增的属性          Item 1 个/Book 1 个/EBook 2 个
      判定为 True 的格数          6 格(含自身)

  **矩阵里 True 的分布就是继承树**——左上角连成一片,说明是从左上往右下长。
  **每个类只写自己新增的属性**(1/1/2),共有的全在 Item 里。
  **这就是 7.2 讲的【B 是 A 的子集】在类图上的样子:一条带空心三角的实线。**

实测:True 共 6 格(含自身),矩阵形状是左下角的三角形。 自己新增的属性 1/1/2,共有的 code 只在 Item 里写一次。 这个三角形就是类图上的那条空心三角线——矩阵与图是同一件事的两种写法。

30 秒实验

  1. 给你项目里最深的一条继承链做一次 issubclass 矩阵。
  2. 数一数有没有哪个属性被三个类各抄了一遍。

常见误区

  1. 把继承画成【父类指向子类】。三角必须指向父类。
  2. 在每个子类里重抄父类的共有属性。那就是 4.9 说的重复定义。
自测三问(点开对答案) 1. 继承在集合论里是什么? —— 子集关系:子类是父类的子集,用 `issubclass` 判定。 2. 实测矩阵里几格 True? —— 6 格(含对角线)——对角全 True 说明继承关系是自反的。 3. 为什么每个类只写新增属性? —— 共有部分写在祖先里一次,避免重复定义,改的时候只改一处。

相关笔记