继承和派生
继承介绍
继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,新建的类可称为子类或派生类,父类又可称为基类或超类
class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1(ParentClass1): #单继承 pass class SubClass2(ParentClass1,ParentClass2): #多继承 pass
通过类的内置属性__bases__可以查看类继承的所有父类
>>> SubClass2.__bases__ (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
在Python2中有经典类与新式类之分,没有显式地继承object类的类,以及该类的子类,都是经典类,显式地继承object的类,以及该类的子类,都是新式类。而在Python3中,即使没有显式地继承object,也会默认继承该类,如下
>>> ParentClass1.__bases__ (<class ‘object'>,) >>> ParentClass2.__bases__ (<class 'object'>,)
因而在Python3中统一都是新式类,关于经典类与新式类的区别,我们稍后讨论
提示:object类提供了一些常用内置方法的实现,如用来在打印对象时返回字符串的内置方法__str__
继承与抽象
要找出类与类之间的继承关系,需要先抽象,再继承。抽象即总结相似之处,总结对象之间的相似之处得到类,总结类与类之间的相似之处就可以得到父类
子类可以继承/遗传父类所有的属性,因而继承可以用来解决类与类之间的代码重用性问题。比如我们按照定义Student类的方式再定义一个Teacher类
class Teacher: school='清华大学' def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age def teach(self): print('%s is teaching' %self.name)
类Teacher与Student之间存在重复的代码,老师与学生都是人类,所以我们可以得出如下继承关系,实现代码重用 class People: school='清华大学' def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age class Student(People): def choose(self): print('%s is choosing a course' %self.name) class Teacher(People): def teach(self): print('%s is teaching' %self.name) Teacher类内并没有定义__init__方法,但是会从父类中找到__init__,因而仍然可以正常实例化,如下 >>> teacher1=Teacher('lili','male',18) >>> teacher1.school,teacher1.name,teacher1.sex,teacher1.age ('清华大学', 'lili', 'male', 18)
属性查找
有了继承关系,对象在查找属性时,先从对象自己的__dict__中找,如果没有则去子类中找,然后再去父类中找……
>>> class Foo: ... def f1(self): ... print('Foo.f1') ... def f2(self): ... print('Foo.f2') ... self.f1() ... >>> class Bar(Foo): ... def f1(self): ... print('Foo.f1') ... >>> b=Bar() >>> b.f2() Foo.f2 Foo.f1
b.f2()会在父类Foo中找到f2,先打印Foo.f2,然后执行到self.f1(),即b.f1(),仍会按照:对象本身->类Bar->父类Foo的顺序依次找下去,在类Bar中找到f1,因而打印结果为Foo.f1
父类如果不想让子类覆盖自己的方法,可以采用双下划线开头的方式将方法设置为私有的
>>> class Foo: ... def __f1(self): # 变形为_Foo__fa ... print('Foo.f1') ... def f2(self): ... print('Foo.f2') ... self.__f1() # 变形为self._Foo__fa,因而只会调用自己所在的类中的方法 ... >>> class Bar(Foo): ... def __f1(self): # 变形为_Bar__f1 ... print('Foo.f1') ... >>> >>> b=Bar() >>> b.f2() #在父类中找到f2方法,进而调用b._Foo__f1()方法,同样是在父类中找到该方法 Foo.f2 Foo.f1

浙公网安备 33010602011771号