python 单继承、多继承、菱形继承

单继承与多继承

单继承:一个类只能继承一个父类的方式。
多继承:一个类可以继承多个父类的方式。

单继承:(生物角度)
人类->哺乳类动物->动物->生物->有机物....

多继承:(社会角度)

舞蹈老师(教舞蹈) 体育老师(运动) 爸爸(抽烟) 妈妈(打扫卫生)

我(舞蹈,运动,抽烟,打扫卫生)

单继承案例:
父类:
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‘>

原文地址:https://www.cnblogs.com/lws865/p/10851972.html

时间: 2024-02-18 19:36:38

python 单继承、多继承、菱形继承的相关文章

C++反汇编第四讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.

目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码: class Father1 { public: Father1(){}//空构造 virtual ~Father1(){} //空析构 virtual void Player(){} //玩耍的函数 int m_price;//金钱 }; class Father2 { public: Father2(){} virtual ~F

C++之菱形继承

当我们谈C++时,我们谈些什么? 封装,继承,多态.这是C++语言的三大特性,而每次在谈到继承时我们不可避免的要谈到一个很重要的问题--菱形继承. a.菱形继承是什么 如上图,菱形继承即多个类继承了同一个公共基类,而这些派生类又同时被一个类继承.这么做会引发什么问题呢,让我们来看一段代码吧! #include<iostream> using namespace std; class Base { protected: int _base; public: void fun() { cout &

菱形继承

学习了C++的继承,觉得菱形继承是比较难懂的一部分,通过了解菱形继承,我们可以了解编译器是如何工作的,下面介绍一下菱形继承在内存中的实现方式. 首先简单了解一下虚继承,下面父类和子类的大小分别是多少? class Base { public:              virtual void fun1()             {                         cout << "Base::fun1()" << endl;         

【C++】虚拟菱形继承的解析

在继承中经常会遇到这种情况:有一个超类A,子类B1,B2继承了A,而类D又继承了父类B1,B2.在这种情况下如果按照我们以前的正常的菱形继承的话会有一个问题是子类C会继承两次超类A中的成员,当在C中想访问继承来自B1,B2中A的元素会出现两个问题: 问题一.数据的冗余 问题二.访问的二意性 出现了这种问题那么我们该如何解决呢? C++中为了解决这个问题引入了虚拟菱形继承,那么虚拟菱形继承是怎么解决的呢? 首先给大家先画两个图比较下菱形继承和虚拟菱形继承在继承时在内存中的成员分布情况: 一. 菱形

菱形继承问题

#coding:utf-8 # python2中指定文件头'''1.菱形继承 当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承 2.菱形继承的问题: python2区分经典类与新式类,如果子的继承是一个菱形继承,那么经典类与形式的区别为? 经典类下查找属性:深度优先查找 深度查找:比如A(B,C,D),深度查找就是A沿着B一路查找下去,直到世界尽头(最后一个父类), 然后才会跳到C查找,找到最后再跳到C 新式类下查找属性:广度优先查找 A(B,C,D)沿着A-B 不插着最后一个

C++中的类继承之单继承&amp;多继承&amp;菱形继承

 C++中的类继承之单继承&多继承&菱形继承 单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可以继承多个父类的特性.多继承可以看作是单继承的扩展.派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承.多继承下派生类的构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用.同时,派生类的参数个数必须包

c++继承汇总(单继承、多继承、虚继承、菱形继承)

一.C++中的对象模型 1. 概念 语言中直接支持面向对象程序设计的部分: 对于各种支持的底层实现机制.(没看懂……) 2. 类中的成员分类 a) 成员函数 i. static function ii. non static function iii. virtual function b)  数据成员 i. static member data ii. non static member data 3. C++对象模型 a) 类对象内存布局中的包括 i. non static member d

python 菱形继承问题究极版

如果只是正常的菱形继承,经典类(python2中最后一个父类不继承object类)是深度优先,即会从左边父类开始一路走到底 新式类(最后一个父类继承了object类)是广度优先,即从左边父类开始继承,留着最后一个类不继承 # 此处只打印新式类正常菱形继承时的顺序,python2中经典类的顺序是F->D->B->A->E->C 1 class A(object): 2 pass 3 4 5 class B(A): 6 pass 7 8 9 class C(A): 10 pass

Python面向对象之类的封装、继承与多态

Python面向对象中类的三大特性,即封装.继承与多态,同时也是所有语言在面向对象编程中的重要特性,下面用实际的代码部分针对每一种特性做出说明. 一.封装 顾名思义,封装即把我们想要的内容封装到某个地方,因此在这里记录两个问题,一是如何封装.二是如何调用封装的内容. 1.封装数据 class Company:     def __init__(self, dept, leader):         self.dept = dept         self.leader = leader