面向对象的三个特性:继承、多态、封装。
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个类,父类又可成为基类或超类,新建的类称为派生类或子类。
- 父类一定要在子类之前,
- 一个类可以被多个类继承,
- 一个类,可以继承多个父类(只在python有多继承)
- 查看继承了哪些类方法:
类名.__bases__
- 抽象化:抽取类似或者比较像部分。
- 派生属性:父类中无的属性,在子类中出现
- 派生方法:父类中无的方法,在子类中出现
举例:
#继承:可节省代码
class Animal:#抽象化,作为父类
def __init__(self,name,aggr,hp):
self.name=name
self.aggr=aggr
self.hp=hp
def eat(self):
print('吃药回血')
self.hp+=100
class Dog(Animal):
def __init__(self,name,aggr,hp,kind):
Animal.__init__(self,name,aggr,hp)#还要传self进去,这个self是指定了dog的self
self.kind=kind #派生属性
def bite(self,person):#派生方法
person.hp-=self.aggr
class Person(Animal):
def hit(self,dog):
dog.hp-=self.aggr
Jack=Dog('Jack',30,500,'哈士奇')
print(Jack.aggr)→30
只要是子类的对象调用,子类中有的名字,一定用子类名,子类中无才找父类,如父类也没有就报错。如果父类、子类都有的名字,就用子类的。如果还想用父类的,单独调用父类。
如果既想实现新的功能也想使用父类原本的功能,不需要在子类中再调用父类,一定要传self参数。
新式类 继承object类的才是新式类 广度优先
经典类 如果你直接创建一个类在2.7中就是经典类 深度优先
print(D.mro())#查看类的继承顺序
D.mro()
单继承 : 子类有的用子类 子类没有用父类
多继承:我们子类的对象调用一个方法,默认是就近原则,找的顺序是类名.mro()→可查看继承顺序。
python2.7 新式类和经典类共存,新式类要继承object
python3 只有新式类,默认继承object
经典类和新式类还有一个区别 mro方法只在新式类中存在
super 只在python3中存在
super的本质 :①不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的。②在类的__init__中使用supper(),相当于调用父类,不用再传self参数,③supper()只是新式类中有。④supper()也可在类的外部使用,但必须传类名和对象名,⑤是根据mro广度优先顺序找上一个类。
钻石继承(广度优先):
广度优先
如果父类一样,就会先广后深。
如果不一样,就会先深后广。
小乌龟
继承总结
继承 : 什么是什么的关系
单继承:
- 先抽象再继承,几个类之间的相同代码抽象出来,成为父类
- 子类自己没有的名字,就可以使用父类的方法和属性
- 如果子类自己有,一定是先用自己的
- 在类中使用self的时候,一定要看清楚self指向谁
多继承 :
新式类和经典类:
- 多继承寻找名字的顺序 : 新式类广度优先,经典类深度优先
- 新式类中 有一个类名.mro方法,查看广度优先的继承顺序
- python3中 有一个super方法,根据广度优先的继承顺序查找上一个类