Python继承机制详解(附带实例)
假设 Python 程序中定义了 Player 球员类,现在想要再创建一个新的类 CF 代表前锋球员,该类同样具有球员的姓名和年龄等类的变量,同样需要打印球员个人信息的类的方法。
要实现 Player 类又要重新写一遍与球员类几乎一样的代码吗?答案是否定的。
面向对象编程提供了继承的机制。由于球员的种类很多,前锋是其中一种,因此 Player 类包含 CF 类,Player 类是 CF 类的父类,通过 class CF(Player) 的定义即可将 Player 类继承给 CF 类,即:
子类继承父类,拥有父类的全部功能。由于前锋球员除姓名和年龄之外,还有一个重要的衡量指标,就是进球数,因此需要为 CF 类创建新的属性 goal,即:
继承是面向对象编程的又一个重要特性。通过继承,子类不仅可以将父类的功能完全继承过来,还可以在父类的基础上扩展新的功能。
例如:
可以看出,通过多重继承,D 拥有了所有父类的功能。多重继承的目的是从多个继承树中分别选择并继承出子类,以便组合出新的功能。
举个例子,Python 的网络服务器有 TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,服务器运行模式有多进程 ForkingMixin 和多线程 ThreadingMixin 两种。
创建多进程模式的 TCPServer,通过多重继承可以很轻松地实现,即:
创建多线程模式的 UDPServer,可分别继承 UDPServer 和 ThreadingMixin,即:
使用 super() 方法可以解决该问题,即:
要实现 Player 类又要重新写一遍与球员类几乎一样的代码吗?答案是否定的。
面向对象编程提供了继承的机制。由于球员的种类很多,前锋是其中一种,因此 Player 类包含 CF 类,Player 类是 CF 类的父类,通过 class CF(Player) 的定义即可将 Player 类继承给 CF 类,即:
class Player(object): name = "" age = 0 def printInfo(self): print('name:%s,age:%d' % (self.name, self.age)) class CF(Player): pass messi = CF() messi.name = 'messi' messi.age = 30 messi.printInfo()运行结果为:
name:messi,age:30由程序可知,定义 CF 类时引用 Player 变量就是继承了 Player 类,CF 类虽然什么都没做,但拥有了 Player 类的所有特性,包含变量和方法。
子类继承父类,拥有父类的全部功能。由于前锋球员除姓名和年龄之外,还有一个重要的衡量指标,就是进球数,因此需要为 CF 类创建新的属性 goal,即:
class Player(object): name = "" age = 0 def printInfo(self): print('name:%s,age:%d' % (self.name, self.age)) class CF(Player): goal = 0 def printInfo(self): print('name:%s,age:%d,goal:%d' % (self.name, self.age, self.goal)) messi = CF() messi.name = 'messi' messi.age = 30 messi.goal = 91 messi.printInfo()运行结果为:
name:messi,age:30,goal:91
CF 类有了新的属性 goal 之后,想要再次通过父类 printInfo() 的方法打印个人信息显然是不满足条件的,需要对 printInfo() 方法进行重写,将 goal 信息也打印出来。继承是面向对象编程的又一个重要特性。通过继承,子类不仅可以将父类的功能完全继承过来,还可以在父类的基础上扩展新的功能。
Python多重继承
继承是面向对象编程的一个重要特性,通过继承,子类就可以拥有父类的所有功能。除了从一个父类继承,Python 还允许从多个父类继承,被称为多重继承。例如:
class A(object): def __init__(self): print('init class A') class B(A): def __init__(self): A.__init__(self) print('init class B') class C(A): def __init__(self): A.__init__(self) print('init class C') class D(B, C): def __init__(self): B.__init__(self) C.__init__(self) print('init class D') d = D()运行结果为:
init class A init class B init class A init class C init class D在程序中,A 为基础父类;
- B、C 从 A 继承,为单继承;
- D 既继承了 B 又继承了 C,为多重继承。
可以看出,通过多重继承,D 拥有了所有父类的功能。多重继承的目的是从多个继承树中分别选择并继承出子类,以便组合出新的功能。
举个例子,Python 的网络服务器有 TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,服务器运行模式有多进程 ForkingMixin 和多线程 ThreadingMixin 两种。
创建多进程模式的 TCPServer,通过多重继承可以很轻松地实现,即:
class MyTCPServer(TCPServer, ForkingMixin)
创建多线程模式的 UDPServer,可分别继承 UDPServer 和 ThreadingMixin,即:
class MyUDPServer(UDPServer, ThreadingMixin)
Python super()方法
继续回到实例程序,虽然实现了多重继承的功能,但是仔细观察会发现一个问题,就是公共父类 A 的初始化方法被调用了多次,显然是不合理的。使用 super() 方法可以解决该问题,即:
class A(object): def __init__(self): print('init class A') class B(A): def __init__(self): super(B, self).__init__() print('init class B') class C(A): def __init__(self): super(C, self).__init__() print('init class C') class D(B, C): def __init__(self): super(D, self).__init__() print('init class D') d = D()运行结果为:
init class A init class C init class B init class D