
3.2.6 类的继承
类是一个模板,在创建新类时,可以在其他已有模板上添加新的内容,也可以改写已有模板上的变量和函数,形成新的模板,这就是类的继承。继承是面向对象编程的重要特征之一。
1.继承与父类的初始化
通过继承可以实现代码的重用,理顺类之间的关系。被继承的类是父类,新建的类是子类。新建一个类时,例如class childClass(fatherClass1,fatherClass2,...),其中fatherClassi是父类。一个类可以继承多个父类,父类之间用逗号隔开,子类继承父类除私有数据之外的所有数据。
用子类实例化一个对象时,会立刻自动执行子类的__init__()函数,但不会执行父类的__init__()函数。可以在子类的__init__()函数体中加入super().__init__()语句,这样就会同时执行父类的初始化函数。例如下面的程序,先创建了person类,person类中有name属性和setName()方法;接下来创建了student类,student类是从person类继承而来的,因此student类中有name属性和setName()方法,在student类中又添加了number属性和score属性,以及setNumber()方法和setScore()方法,然后用student类实例化liming,并调用三个方法为属性赋值。

2.方法重写
子类继承父类时,如果父类的某些函数或变量已经不适合子类的要求,可以在子类中修改父类的函数或者删除父类的变量。修改父类的函数只需在子类中重新写一个与父类同名的函数即可。在用类实例化对象后,对象调用与父类同名的方法时,调用的是子类的函数,而不是父类的函数。例如下面的程序,person中有实例变量name和address,还有一个设置姓名的函数setName(),在子类student继承person,在student的初始化函数中用del self.address删除从父类继承的address变量,重写了父类的setName()函数。

3.基类object
新建立一个类时,如果没有类可以继承,可以选择object作为父类。object类是Python的默认类,提供了很多内置方法,Python中字符串、列表和字典等对象都继承了object类的方法。继承了object的类属于新式类,没有继承object的类属于经典类。在Python3.x中默认所有的自定义类都会继承object类,Python3.x的所有类都是object的子类;在Python2中不继承object的类是经典类。object类的内置函数如表3-1所示。
表3-1 object类的内置函数

object类提供的函数都是比较深层次的操作,当探测到某种动作发生或处于某种状态时,会自动运行相应的函数,这些函数可以在自定义类中重新定义。例如下面的代码中__getattr__()、__setattr__()、__delattr__()和__str__(),当给属性赋值,或者给一个不存在的属性赋值时,会自动触发__setattr__()函数;当读取一个属性的值,或者读取一个不存在的属性值时,会自动触发__getattr__()函数;当删除一个属性时,会自动触发__delattr__()函数;当打印一个实例时,会自动触发__str__()函数。
