# 继承概述
- 子类可以继承父类的所有属性和方法(包含Init构造方法),也可以重写父类的所有属性和方法。
- 继承可以用来扩展父类的功能,或者实现接口多态(一种接口多种实现)。
- 大量工程实践表明,重度的行为继承会导致系统过度复杂和臃肿,反而会降低灵活性。
# 继承示例
class A(object): def __init__(self, name): self.name = name def print(self): print("Hello " + self.name) class B(A): """ 继承父类 A 的 构造方法 和 print方法,以及 name属性 """ pass if __name__ == '__main__': b = B("Python") b.print()
执行结果 >
Hello Python
class A(object): def __init__(self, name): self.name = name def print(self): print("Hello " + self.name) class B(A): """ 继承父类 A 的 构造方法 和 name属性 重写父类 A 的 print方法 """ def print(self): print("I Love " + self.name) if __name__ == '__main__': b = B("Python") b.print() 执行结果> I Love Python
class A(object): def __init__(self, name): self.name = name def print(self): print("Hello " + self.name) class B(A): """ 扩展父类 A 的 init构造方法 重写父类 A 的 print方法 """ def __init__(self, name, age): self.age = age super(B, self).__init__(name) # 通过super调用父类的构造方法 def print(self): print("I Love " + self.name) print("Age " + str(self.age)) if __name__ == '__main__': b = B(name="Python", age=22) b.print() 执行结果> I Love Python Age 22
class A(abc.ABC): def __init__(self, name): self.name = name def print(self): print("Hello " + self.name) # 要求子类必须实现hello方法, 否则会报异常:TypeError: Can't instantiate abstract class xxx with abstract methods xxx @abc.abstractmethod def hello(self): pass
# 原始功能 class A(object): def __init__(self, name): self.name = name def print(self): print("I Love: " + self.name) # 不直接通过Class A的实例调用print方法,而是通过另外一个函数调用 # 这样的好处是对Class A进行扩展后,原来的调用方式不变 def func(type_a): type_a.print() # 只要求实现了print方法的对象即可 if __name__ == '__main__': func(A("Python")) 执行结果> I Love: Python -------------------------- # 后来需要扩展Class A 的 print功能 class B(A): def print(self): print("I Love Love Love: " + self.name) if __name__ == '__main__': func(B("Python")) # 调用方式不变 执行结果> I Love Love Love: Python
# 多继承
注:多继承增加了继承的复杂度,因此尽量不要使用多继承。
- Python的类可以继承多个类,Java和C#中则只能继承一个类。
- Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
-
- 当类是经典类时,多继承情况下,会按照深度优先方式查找
- 当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,
从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。