继承
当然,如果不支持继承,语言特性就不配称为“类”。派生类定义的语法如下所示:
class DerivedClassName(BaseClassName):<statement-1>...<statement-N>
必须在包含派生类定义的作用域中定义名称 BaseClassName。也允许使用其他任意表达式代替基类名称。例如,当基类在另一个模块中定义时,这可能很有用:
class DerivedClassName(modname.BaseClassName):
派生类定义的执行过程与基类相同。当类对象被构造时,基类会被记住。这用于解析属性引用:如果在类中找不到请求的属性,则搜索将继续查找基类。如果基类本身是从其他类派生的,则递归应用此规则。
派生类的实例化没有什么特别之处:DerivedClassName() 创建该类的新实例。方法引用的解析如下:搜索相应的类属性,必要时沿着基类链向下搜索,如果生成函数对象,则方法引用有效。
派生类可以重写其基类的方法。由于方法在调用同一对象的其他方法时没有特权,因此调用同一基类中定义的另一个方法的基类的方法可能最终调用重写它的派生类的方法。(对于 C++ 程序员来说,Python 中的所有方法事实上都是 virtual 的)。
派生类中的重写方法实际上可能希望扩展而不是简单地替换同名的基类方法。有一种直接调用基类方法的简单方法:只需调用 BaseClassName.methodname(self, arguments)。这对客户端有时也很有用。(请注意,只有当基类在全局范围内可以作为 BaseClassName 访问时,这才有效。)
Python 有两个用于继承的内置函数:
● 使用 isinstance() 检查实例的类型:isinstance(obj, int) 只有在 obj.__class__ 是 int 或从 int 派生的类才返回 True。
● 使用 issubclass() 检查类继承:issubclass(bool, int) 为 True,因为 bool 是 int 的子类。但是,issubclass(float, int) 为 False,因为 float 不是 int 的子类。
多重继承
Python 还支持多重继承。具有多个基类的类定义如下所示:
class DerivedClassName(Base1, Base2, Base3):<statement-1>...<statement-N>
在最简单的情况下,可以将对继承自父类的属性的搜索视为从左到右的深度优先,而不是在层次结构中存在重叠的同一类中搜索两次。因此,如果在 DerivedClassName 中未找到属性,则在 Base1 中搜索该属性,然后(递归地)在 Base1 的基类中搜索该属性,如果未找到该属性,则在 Base2 中搜索该属性,依此类推。
事实上,情况比这稍微复杂一些;方法解析顺序会动态更改,以支持对 super() 的协作调用。这种方法在其他一些多重继承语言中称为 call-next-method,它比单一继承语言中的 super 调用更强大。
动态排序是必要的,因为多重继承的所有情况都显示一个或多个菱形关系(其中至少一个父类可以通过最底层类的多个路径访问)。例如,所有类都继承自 object,所以任何情况下的多重继承都会提供多个到达 object 的路径。为了避免基类被多次访问,动态算法线性化搜索顺序,保持每个类中指定的从左到右顺序,只调用每个父类一次,并且是单调的(这意味着可以在不影响父类优先顺序的情况下对类进行子类化)。综上所述,这些属性使得设计具有多重继承的可靠和可扩展类成为可能。
官方文档:
https://docs.python.org/3.9/tutorial/classes.html




