在某种情况下,一个类会有子类(或称派生类)。子类比原本的类(称为父类或基类)要更加具体化。例如,Student 这个类可能会有它的子类 MiddleSchoolStudent 和 CollegeStudent 。子类会继承父类的属性(变量和方法),并且也可包含它们自己的。我们假设 Dog 这个类有一个方法叫做 bark() 和一个属性叫做 color。它的子类(如 ChineseRuralDog 或 GermanShepherdDog)会继承这些成员。这意味着只需要将相同的代码写一次。
这种子类具有父类的属性和方法的机制,称为继承(Inheritance)。
继承可避免相同代码的重复书写,减少代码的数量。继承是面向对象编程的三大基本特征之二。
定义子类#
子类定义的语法如下:
class DerivedClassName(BaseClassName):
...
即需要将父类 BaseClassName 列在子类 DerivedClassName 头部的括号内。
在使用子类及其实例化对象时,如果引用了其属性,并且在子类中找不到此属性,会转往基类中查找此属性,如果基类也继承自其它某个类,此搜索将被递归地应用。
示例:
class Dog:
def __init__(self):
self.name = None
self.breed = None
self.bark_mode = '汪…汪…'
def bark(self):
print(f'一只名为{self.name}的{self.breed}在{self.bark_mode}地叫着。')
class ChineseRuralDog(Dog): pass
my_dog = ChineseRuralDog()
my_dog.name = '大黄'
my_dog.breed = '中华田园犬'
my_dog.bark() # 一只名为大黄的中华田园犬在汪…汪…地叫着。
以下示例无法运行,请分析原因:
class Dog:
def __init__(self):
self.name = None
self.breed = None
self.bark_mode = '汪…汪…'
def bark(self):
print(f'一只名为{self.name}的{self.breed}在{self.bark_mode}地叫着。')
class ChineseRuralDog(Dog):
def __init__(self):
self.breed = '中华田园犬'
my_dog = ChineseRuralDog()
my_dog.name = '大黄'
my_dog.bark() # AttributeError: 'ChineseRuralDog' object has no attribute 'bark_mode'
又一个示例:
class Shape:
def draw(self): ...
def edge_length(self): ...
class Polygon(Shape):
def area(self): ...
class Rectangle(Polygon):
def width(self): ...
def height(self): ...
rect = Rectangle()
rect.draw()
rect.area()
rect.width()
多重继承#
一个子类可以有多个父类,此种继承关系称为多重继承。如下所示:
class DerivedClassName(Base1, Base2, Base3):
...
在搜索从父类所继承的属性属性时,会按照深度优先、从左至右的顺序进行,当层次结构中存在重叠时不会在同一个类中搜索两次。因此,如果某一属性在 DerivedClassName 中未找到,则会到 Base1 中搜索它,然后(递归地)到 Base1 的基类中搜索,如果还未找到,再到 Base2 中搜索,依此类推。
示例:
class HeadingMachine:
"""掘进机"""
def driving(self): ...
class RockDrill:
"""凿岩机"""
def drill(self): ...
class BolterMiner(HeadingMachine, RockDrill):
"""掘锚机"""
def other(self): ...
另一个示例:
class Reader:
def read(self): ...
class Writer:
def write(self): ...
class File(Reader, Writer):
def other(self): ...
检查继承关系#
Python 有两个内置函数可被用于继承机制:
isinstance()检查一个实例的类型,isinstance(obj, int)仅会在obj.__class__为int或某个派生自int的类时为True。issubclass()检查类的继承关系,issubclass(bool, int)为True,因为bool是int的子类。 但是,issubclass(float, int)为False,因为float不是int的子类。