单继承与多继承
单继承:一个类只能继承一个父类的方式。
多继承:一个类可以继承多个父类的方式。
单继承:(生物角度)
人类->哺乳类动物->动物->生物->有机物....
多继承:(社会角度)
舞蹈老师(教舞蹈) 体育老师(运动) 爸爸(抽烟) 妈妈(打扫卫生)
我(舞蹈,运动,抽烟,打扫卫生)
单继承案例:
父类:
pass
子类(父类):
pass
多继承案例:
父类1:
pass
父类2:
pass
父类3:
pass
子类(父类1,父类2,父类3):
pass
多继承的问题所在:菱形继承或者钻石继承中的问题。
菱形继承的bug解决:
MRO列表和super 类
当我们定义一个菱形继承关系的时候,程序会自动生成一个新的MRO列表。
MRO列表: Method Realtion Order 方法关系列表。
MRO列表的生成采用了C3算法完成的。
C3算法的原则:1.子类永远在父类的前面2.同一等级的类,按照子类中的继承顺序摆放
super()调用的时候,不是查找父类!!!! 实际上super是查找MRO列表的上一个类
super()调用对象方法的时候不需要传入对象,自动传入
补充:如果需要查看mro列表,可以使用对象.mro() 方法查看(非必要~)
1.单继承案例
1 #单继承案例
2 '''
3 爷爷类
4 爸爸类
5 儿子类
6 '''
7
8 #爷爷类
9 class GroundFather:
10 #属性
11 skin = '黄色'
12 #方法
13 def say(self):
14 print('说话中')
15
16 #爸爸类
17 class Father(GroundFather):
18 #属性
19 eye = '水汪汪的小眼睛'
20 #方法
21 def walk(self):
22 print('走走~停停中~')
23
24 #儿子类
25 class Son(Father):
26 pass
27
28 #实例化儿子对象
29 erzi = Son()
30 print(erzi)
31 #输出结果:<__main__.Son object at 0x0000018415490C50>
32
33 #调用方法或者属性
34 print(erzi.skin)
35 #输出结果:黄色
36
37 print(erzi.eye)
38 #输出结果:水汪汪的小眼睛
39
40 erzi.say()
41 #输出结果:说话中
42
43 #erzi.walk()
44 #输出结果:
2.多继承案例
1 #多继承案例
2 '''
3 音乐老师类:
4 体育老师类:
5 爸爸类:
6 妈妈类:
7 '''
8 #音乐老师类
9 class MusicTeacher:
10 #属性
11 cloth = '晚礼服'
12 #方法
13 def sing(self):
14 print('门前大桥下,路过一群鸭,快来快来数一数,2,4,6,7,8.。')
15 #体育老师类
16 class SportTeahcer:
17 #方法
18 def run(self):
19 print('跑步功能')
20
21 def jump(self):
22 print('you jump,i jump')
23 #爸爸类
24 class Father:
25 #方法
26 def smoking(self):
27 print('抽烟中~~')
28 #妈妈类
29 class Mother:
30 #方法
31 def clear(self):
32 print('打扫房间。。')
33 #我的类(多继承)
34 class Me(Mother,Father,MusicTeacher,SportTeahcer):
35 pass
36
37 #实例化对象
38 i = Me()
39 #调用成员
40 print(i.cloth)
41 #输出结果:晚礼服
42
43 i.sing()
44 #输出结果:门前大桥下,路过一群鸭,快来快来数一数,2,4,6,7,8.。
45
46 i.jump()
47 #输出结果:you jump,i jump
48
49 i.run()
50 #输出结果:跑步功能
51
52 i.smoking()
53 #输出结果:抽烟中~~
54
55 i.clear()
56 #输出结果:打扫房间。。
3.菱形继承,BUG案例
1 #菱形继承,BUG案例
2 '''
3 A类(动物类)
4 B类(人类)
5 C类(鸟类)
6 D类(鸟人类)
7 '''
8 #动物类 A类
9 class Animal:
10 #发声的方法
11 def say(self):
12 print('Animal类准备开始发音')
13 print('Animal类发音结束')
14
15 #人类 B类
16 class Human(Animal):
17 #发音的方法
18 def say(self):
19 print('Human类准备开始发音')
20 #调用父类中的发音功能
21 Animal.say(self)
22 print('Human类发音结束')
23
24 #鸟类 C类
25 class Bird(Animal):
26 #发音的方法
27 def say(self):
28 print('Bird类准备开始发音')
29 #调用父类的发音功能
30 Animal.say(self)
31 print('Bird类发音结束')
32
33 #鸟人类
34 class BirdMan(Human,Bird):
35 #发音的方法
36 def say(self):
37 print('BirdMan类准备开始发音')
38 #调用人类的发音
39 Human.say(self)
40 #调用鸟类的发音
41 Bird.say(self)
42 print('BirdMan类发音结束')
43
44 #实例化一个鸟人对象
45 bm = BirdMan()
46 #调用说话方法
47 bm.say()
48 '''
49 输出结果:
50 BirdMan类准备开始发音
51 Human类准备开始发音
52 Animal类准备开始发音
53 Animal类发音结束
54 Human类发音结束
55 Bird类准备开始发音
56 Animal类准备开始发音
57 Animal类发音结束
58 Bird类发音结束
59 BirdMan类发音结束
60 '''
61 '''
62 菱形继承中的bug所在,某个方法在继承中被多次调用!。(如果该方法具有唯一或者计时类似的特性则无法使用。)
63 上面案例 Animal类在菱形继承中子类只调用一次但,而Animal类却被调用两次,这就是菱形继承的BUG
64 Animal类准备开始发音
65 Animal类发音结束
66
67 '''
68 #菱形继承中的bug所在,某个方法在继承中被多次调用!。(如果该方法具有唯一或者计时类似的特性则无法使用。)
4.菱形继承,super()解决BUG案例
1 #菱形继承,super()解决BUG案例
2 '''
3 A类(动物类)
4 B类(人类)
5 C类(鸟类)
6 D类(鸟人类)
7 '''
8
9 #动物类 A类
10 class Animal:
11 #发声的方法
12 def say(self):
13 print('Animal类准备开始发音')
14 print('Animal类发音结束')
15
16 #人类 B类
17 class Human(Animal):
18 #发音的方法
19 def say(self):
20 print('Human类准备开始发音')
21 #调用MRO列表中的上一层类的发音功能
22 super().say()
23 print('Human类发音结束')
24
25 #鸟类 C类
26 class Bird(Animal):
27 #发音的方法
28 def say(self):
29 print('Bird类准备开始发音')
30 # 调用MRO列表中的上一层类的发音功能
31 super().say()
32 print('Bird类发音结束')
33
34 #鸟人类
35 class BirdMan(Human,Bird):
36 #发音的方法
37 def say(self):
38 print('BirdMan类准备开始发音')
39 # 调用MRO列表中的上一层类的发音功能
40 super().say()
41 print('BirdMan类发音结束')
42
43 #实例化一个鸟人对象
44 bm = BirdMan()
45 #调用说话方法
46 bm.say()
47 '''
48 输出结果:
49 BirdMan类准备开始发音
50 Human类准备开始发音
51 Bird类准备开始发音
52 Animal类准备开始发音
53 Animal类发音结束
54 Bird类发音结束
55 Human类发音结束
56 BirdMan类发音结束
57 '''
58 #MRO列表 -> BirdMan,Human,Bird,Animal,object
59 #查看super
60 print(super)#super是个类
61 #输出结果:<class 'super'>
来源:oschina
链接:https://my.oschina.net/u/4365953/blog/3541347