Python进阶-XVI 继承 单继承 多继承

 一、初识继承

  1、引入继承

 1 class A(object):
 2     pass  # 父类,基类,超类
 3 
 4 class B:
 5     pass  # 父类,基类,超类
 6 
 7 class A_son(A, B):
 8     pass  # 子类,派生类
 9 
10 class AB_son(A):
11     pass  # 子类,派生类
12 
13 # 一个类 可以被多个类继承
14 # 一个类 可以继承多个父类  —— python里
15 print(A_son.__bases__)
16 print(AB_son.__bases__)
17 print(A.__bases__)  # python3 -新式类# 没有继承父类默认继承object

  2、实例

 1 class Animal:
 2     def __init__(self, name, aggr, hp):
 3         self.name = name
 4         self.aggr = aggr
 5         self.hp = hp
 6         self.func()  # 谁来初始化,就调谁的func方法
 7 
 8     def func(self):
 9         print('animal func')
10 
11 
12 class Dog(Animal):
14     def func(self):
15         print('dog func')
16 
17     def bite(self, person):
18         person.hp -= self.aggr
19 
21 d = Dog('dig', 22, 33)
 3、增加功能
  狗类 吃 喝 看门(guard)
  鸟类 吃 喝 下蛋(lay)
 1 class Animal:
 2     def __init__(self):
 3         print('执行Animal.__init__')
 4         self.func()
 5 
 6     def eat(self):
 7         print('%s eating' % self.name)
 8 
 9     def drink(self):
10         print('%s drinking' % self.name)
11 
12     def func(self):
13         print('Animal.func')
14 
15 
16 class Dog(Animal):
17     def guard(self):
18         print('guarding')
19 
20     def func(self):
21         print('Dog.func')
22 
23 
24 dog = Dog()
25 
26 
27 class Bird(Animal):
28     def __init__(self, name):
29         self.name = name
30 
31     def lay(self):
32         print('laying')

二、单继承

以上实例都是一个类只继承一个类,即单继承。

1、继续原来的例子,增加吃药回血功能

 1 class Animal:
 2     def __init__(self,name,aggr,hp):
 3         self.name = name
 4         self.aggr = aggr
 5         self.hp = hp
 6 
 7     def eat(self):
 8         print('吃药回血')
 9         self.hp+=100
10 
11 class Dog(Animal):
12     def __init__(self,name,aggr,hp,kind):
13         Animal.__init__(self,name,aggr,hp)  #
14         self.kind = kind       # 派生属性
15     def eat(self):
16         Animal.eat(self)   # 如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类
17         self.teeth = 2
18     def bite(self,person):   # 派生方法
19         person.hp -= self.aggr
20 
21 jin = Dog('金老板',100,500,'吉娃娃')
22 jin.eat()
23 print(jin.hp)

增加一个继承类

 1 class Person(Animal):
 2     def __init__(self,name,aggr,hp,sex):
 3         Animal.__init__(self,name,aggr,hp)
 4         self.sex = sex       # 派生属性
 5         self.money = 0       # 派生属性
 6 
 7     def attack(self,dog):
 8         dog.hp -= self.aggr
 9 
10     def get_weapon(self,weapon):
11         if self.money >= weapon.price:
12             self.money -= weapon.price
13             self.weapon = weapon
14             self.aggr += weapon.aggr
15         else:
16             print("余额不足,请先充值")
17 alex = Person('alex',1,2,None)
18 alex.eat()
19 print(alex.hp)
20 
21 jin.bite(alex)
22 print(alex.hp)
View Code
2、总结
父类中没有的属性 在子类中出现 叫做派生属性
父类中没有的方法 在子类中出现 叫做派生方法
只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
如果父类 子类都有 用子类的
如果还想用父类的,单独调用父类的:
父类名.方法名 需要自己传self参数
super().方法名 不需要自己传self
正常的代码中 单继承 === 减少了代码的重复
继承表达的是一种 子类是父类的关系
 1 class Animal:
 2     def __init__(self,name,aggr,hp):
 3         self.name = name
 4         self.aggr = aggr
 5         self.hp = hp
 6     def eat(self):
 7         print('吃药回血')
 8         self.hp+=100
 9 
10 class Dog(Animal):
11     def __init__(self,name,aggr,hp,kind):
12         super().__init__(name,aggr,hp)  # 只在新式类中有,python3中所有类都是新式类
13         self.kind = kind       # 派生属性
14     def eat(self):print('dog eating')
15 
16 jin = Dog('金老板',200,500,'teddy')
17 print(jin.name)
18 jin.eat()
19 super(Dog,jin).eat()
View Code

三、多继承

新式类(python3中都是新式类)中的继承顺序 : 广度优先

非新式类,深度优先

本处都是在python3中运行。

  1、普通多继承例子

 1 class F:
 2     def func(self): print('F')
 3 class A(F):pass
 4     # def func(self): print('A')
 5 class B(A):
 6     pass
 7     # def func(self): print('B')
 8 class E(F):pass
 9     # def func(self): print('E')
10 class C(E):
11     pass
12     # def func(self): print('C')
13 
14 class D(B,C):
15     pass
16     # def func(self):print('D')
17 
18 d = D()
19 # d.func()
20 print(D.mro())
View Code

先找最靠近自己的父类,以此类推!

  2、钻石多继承

 1 class A(object):
 2     def func(self): print('A')
 3 
 4 class B(A):
 5     def func(self):
 6         super().func()
 7         print('B')
 8 
 9 class C(A):
10     def func(self):
11         super().func()
12         print('C')
13 
14 class D(B,C):
15     def func(self):
16         super().func()
17         print('D')
18 
19 b = D()
20 b.func()
21 print(B.mro())
View Code
  3、总结
新式类 继承object类的才是新式类 广度优先
经典类 如果你直接创建一个类在2.7中就是经典类 深度优先
print(D.mro())
D.mro()

单继承 : 子类有的用子类 子类没有用父类
多继承中,我们子类的对象调用一个方法,默认是就近原则,找的顺序是什么?
经典类中 深度优先
新式类中 广度优先

python2.7 新式类和经典类共存,新式类要继承object
python3 只有新式类,默认继承object

经典类和新式类还有一个区别 mro方法只在新式类中存在
super 只在python3中存在
super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的

猜你喜欢

转载自www.cnblogs.com/funyou/p/12024521.html