Python程序设计案例课堂
上QQ阅读APP看书,第一时间看更新

6.7 类的继承

所谓类的继承(inheritance),就是新类继承旧类的属性与方法,这种行为称为派生子类(subclassing)。继承的新类称为派生类(derived class),被继承的旧类则称为基类(base class)。当用户创建派生类后,就可以在派生类内新增或是改写基类的任何方法。

派生类的语法如下:

        class <类名称> [(基类1,基类2, ...)]:
          ["文件字符串"]
        <语句>

一个派生类可以同时继承自许多个基类,基类之间以逗号(,)隔开。

下列是一个基类A与一个基类B:

        >>> class A:
            pass

        >>> class B:
            pass

下列是一个派生类C,继承自一个基类A:

        >>> class C(A):
            pass

下列是一个派生类D,继承自两个基类A与B:

        >>> class D(A, B):
            pass

1.派生类的构造方法

下列是一个基类的定义:

        >>>class Student:
            def __init__(self, name, sex, phone):
                  self.name = name
                  self.sex = sex
                  self.phone = phone
            def printData(self):
                  print ("姓名: ", self.name)
                  print ("性别: ", self.sex)
                  print ("电话: ", self.phone)

这个基类Student有3个成员变量:name(姓名)、sex(性别)和phone(电话)。并且定义两个函数:①__init__()函数是Student类的构造方法。②printData()函数用来打印成员变量的数据。下面创建一个Student类的派生类:

        >>>class Person(Student):
        def __init__(self, name, sex, phone):       #派生类的构造方法
        Student.__init__(self, name, sex, phone)    #调用基类的构造方法

派生类的构造方法必须调用基类的构造方法,而且必须使用完整的基类名称。Student.__init__(self, name, sex, phone)中的self参数,用来告诉基类现在调用的是哪一个派生类。

下列案例创建一个派生类Person的实例变量,并且调用基类Student的函数printData(),来印出数据。

        >>>x = Person("李明峰", "男", "12345678")
        >>>x.printData()
        姓名:  李明峰
        性别:  男
        电话:  12345678

2.命名空间的搜索顺序

当用户在类内编写函数时,要记得类函数的命名空间的搜索顺序。

(1)类的实例。

(2)类。

(3)基类。

下列是3个类:A、B和C。B继承自A, C又继承自B。A、B、C这3个类都有一个相同名称的函数printName()。代码如下:

        >>> class A:
          def __init__(self, name):
                  self.name = name
            def printName(self):
                  print ("这是类A的printName()函数,name = %s" % self.name)

        >>>class B(A):
          def __init__(self, name):
                A.__init__(self, name)
            def printName(self):
                    print ("这是类B的printName()函数,name = %s" % self.name)

        >>> class C(B):
            def __init__(self, name):
                  B.__init__(self, name)
            def printName(self):
                  print ("这是类C的printName()函数,name = %s" % self.name)

下面分别创建A、B、C这3个类的实例,并且调用printName()函数。代码如下:

        >>> A("张晓晓").printName()
        这是类A的printName()函数,name = 张晓晓
        >>> B("胡明月").printName()
        这是类B的printName()函数,name = 胡明月
        >>> C("张一诺").printName()
            这是类C的printName()函数,name = 张一诺

上述代码分析如下。

(1)A("张晓晓").printName()会调用A类的printName()函数。

(2)B("胡明月").printName()会先调用B类的printName()函数,因为已经找到一个printName()函数,所以不会继续往A类查找。

(3)C("张一诺").printName()会先调用C类的printName()函数,因为已经找到一个printName()函数,所以不会继续往B类与A类查找。

3.类的多继承

Python同样有限的支持多继承形式。

【案例6-2】类的多继承(代码6.2.py)。

        #类定义
        class people:
            #定义基本属性
            name = ''
            age = 0
            #定义私有属性,私有属性在类外部无法直接进行访问
            __weight = 0
            #定义构造方法
            def __init__(self, n, a, w):
              self.name = n
              self.age = a
              self.__weight = w
            def speak(self):
              print("%s说:我 %d岁。" %(self.name, self.age))

        #单继承示例
        class student(people):
            grade = ''
            def __init__(self, n, a, w, g):
              #调用父类的构函
              people.__init__(self, n, a, w)
              self.grade = g
            #覆写父类的方法
            def speak(self):
              print("%s说:我 %d岁了,我在读 %d年级
        "%(self.name, self.age, self.grade))

        #另一个类,多重继承之前的准备
        class speaker():
            topic = ''
            name = ''
            def __init__(self, n, t):
              self.name = n
              self.topic = t
            def speak(self):
              print("我叫 %s,我是一名人民教师,我演讲的主题是 %s"%(self.name, self.topic))

        #多重继承
        class sample(speaker, student):
            a =''
            def __init__(self, n, a, w, g, t):
              student.__init__(self,n,a,w,g)
              speaker.__init__(self,n,t)

        test = sample("张明明",25,80,4, "什么是爱")
        test.speak()   #方法名同,默认调用的是在括号中靠前的父类的方法

保存并运行程序,结果如下:

        C:\Users\Administrator>python d:\python\ch06\6.2.py
        我叫 张明明,我是一名人民教师,我演讲的主题是 什么是爱

在本案例中,定义了一个people类,定义一个student类继承自people类,实现单继承效果。为了实现多继承效果,这里又定义了一个speaker类,然后定义sample类继承自speaker类和student类。