首页 > 编程笔记 > Python笔记 阅读:15

Python继承机制详解(附带实例)

假设 Python 程序中定义了 Player 球员类,现在想要再创建一个新的类 CF 代表前锋球员,该类同样具有球员的姓名和年龄等类的变量,同样需要打印球员个人信息的类的方法。

要实现 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 为基础父类;
可以看出,通过多重继承,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

相关文章