面向对象---继承
一.继承
1.继承的概念:
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类(多个父类是python特有的)
父类又可称为基类或超类,新建的类称为派生类或子类
2.类的继承分为:单继承和多继承
class Parent1:pass
class Parent2:pass
class Children( Parent1):pass #单继承
class Children( Parent1,Parent2):pass #多继承
查看继承 base和bases 在python3中所有的类都集成object
print(Children.__base__) #<class '__main__.Parent1'> print(Children.__base__) #<class '__main__.Parent1'> print(Children.__bases__) #(<class '__main__.Parent1'>, <class '__main__.Parent2'>) #查看继承,只查看父类,不管父类的父类。在python3中所有的类都集成object print(Parent2.__bases__) #(<class 'object'>,)
3.继承与抽象(先抽象再继承)
3.1抽象即抽取类似或者说比较像的部分。抽象最主要的作用是划分类别
猫类 : 吃eat 喝drink 睡sleep 爬树climb # 狗类 : 吃eat 喝drink 睡sleep 看家watch class Pet: def __init__(self,name,kind,food): self.name = name self.kind = kind self.food = food def eat(self): print('%s吃%s'%(self.name,self.food)) class Cat(Pet): def climb(self): # 派生方法 print('%s在爬树' % self.name) class Dog(Pet): def watch(self): # 派生方法 print('%s在看家' % self.name) tom = Cat('Tom','暹罗猫','猫粮') #子类使用名字(方法和静态变量),如果在子类中没有,就使用父类的
print(tom.name) #子类使用名字(方法和静态变量),如果在子类中没有,就使用父类的.此时父类中init中的self就是tom
实例化这个类
# 创建一个空对象
# 执行__init__方法:子类没有用父类的
3.2父类和子类拥有同名的方法时,子类的对象只会调用子类的
如果想要调用父类的方法,需要 父类名.方法名(self,其他参数)
子类中有自己的属性如sex,kind。在子类的init中再调父类的init
class Animal: def __init__(self,name,aggr,hp): self.name = name # 对象属性 实例属性 self.aggr=aggr self.hp = hp class Person(Animal): def __init__(self,name,sex,aggr,hp): self.sex= sex # 派生属性 Animal.__init__(self,name,aggr,hp) def attack(self,dog): print('%s打了%s'%(self.name,dog.name)) dog.hp -= self.aggr class Dog(Animal): def __init__(self,name,kind,aggr,hp): self.kind= kind Animal.__init__(self,name,aggr,hp) def bite(self,person): print('%s咬了%s'%(self.name,person.name)) person.hp -= self.aggr hei = Dog('小黑','teddy',260,10000) alex = Person('alex','female',1,250)
4.super关键字 只存在python3中
单继承中 super会寻找父类
且在使用super调用父类方法的时候不需要再传self参数
# super().__init__(name,aggr,hp) 等于 super(Person,self).__init__(name,aggr,hp)
class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr=aggr self.hp = hp def eat(self): print("在Animal中") class Person(Animal): def __init__(self,name,sex,aggr,hp): self.sex= sex # Animal.__init__(self,name,aggr,hp) super().__init__(name,aggr,hp) def eat(self): print("在Person中") #Animal.eat(self) #同时用父类中的方法 #super().eat() alex=Person('alex','female',1,250) #只用父类中的方法 # Animal.eat(alex) # super(Person,alex).eat()
5.单继承问题。属性的引用,会先从子类中寻找,子类中不存在,就去父类中找,直到最顶级的父类
不要发生循环继承
依赖倒置原则 :高层模块不应该依赖低层模块
class A: def wahaha(self):print('in A') class B(A): def wahaha(self):print('in B') class C(B): def wahaha(self):print('in C') class D(C):pass d = D() d.wahaha() #in C
6.多继承问题:属性的引用,会先从子类中寻找,子类中不存在。会根据继承的顺序去用执行
class A:pass # def qqxing(self): # print('in A') class B: def qqxing(self): print('in B') class C: def qqxing(self): print('in C') class D(B,A,C): pass d = D() d.qqxing()
砖石继承问题
1.B和C继承A,D继承B和C.print(F.mro()) 查看继承顺序
class A: def display(self): print('in A') class B(A): def display(self): print('in B') class C(A): def display(self): print('in C') class D(B,C): def display(self): print('in D') d=D() d.display() #D中不存在这个方法的话,就去B中找,B中不存在就去C中找,仍不存在就去A中找 print(D.mro()) #<__main__.D'>, <__main__.B'>, <_main__.C'>, <__main__.A'>, <class 'object'>]
2.B和C继承A,D继承B,E继承C,F继承D,E
#查找顺序:1.F 2.D 3.B 4.E 5.C 6.A
3.super在单继承和多继承中
单继承找父类
class A: def display(self): print('in A') class B(A): def display(self): super().display() #在单继承中找父类 print('in B') class C(A): def display(self): print('in C') class D(B):pass d=D() d.display() #in A in B
super在多继承 根据mro(广度优先)顺序的
class A: def display(self): print('in A') class B(A): def display(self): super().display() print('in B') class C(A): def display(self): print('in C') class D(B,C):pass d=D() d.display() #in C in B
继承问题总结
1.python3中的所有类 都默认继承object。super只存在python中
2.查看继承的顺序D.mro()
3.新式类:如果一个类 继承了object 这个类就被称为新式类
经典类:没有继承object类 就被称为经典类 python2
4.深度优先 广度优先 都是一种遍历算法,把这个图中所有的项都走一遍,且不会重复
5.经典类和新式类的区别:
经典类 遵循 深度优先算法 且没有mro方法 python2
新式类 继承object 遵循 广度优先算法 有mro方法 python3
在python中如果把经典类变成新式类,在最顶级父类类名加上(obj)
6.super:单继承中 super就是找父类
多继承 super寻找的轨迹是根据mro(广度优先)顺序的
7.继承的作用:
减少代码的重用
提高代码可读性
规范编程模式
8.名词
抽象:抽象即抽取类似或者说比较像的部分。是一个从具题到抽象的过程。
继承:子类继承了父类的方法和属性
派生:子类在父类方法和属性的基础上产生了新的方法和属性