面向对象 - 1.继承/2.派生/3.继承的实现原理
1.继承:指的是类与类之间的关系,是一种什么是什么的关系,继承的功能是解决代码的重用问题,继承是一种创建新类的方式
python 中新建的类可以继承一个或多个父类(基类或超类)
新建的类称为派生类或子类
对象之间相似的特征-------类
类之间相似的特征 ---- 父类
继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。
1 # class ParentClass1: 2 # pass 3 # 4 # class ParentClass2: 5 # pass 6 # 7 # class SubClass1(ParentClass1): # 子类/派生类 父类/基类 8 # pass 9 # 10 # class SubClass2(ParentClass1,ParentClass2): 11 # pass 12 # 13 # print(SubClass1.__bases__) 14 # print(SubClass2.__bases__) 15 16 class Hero: 17 x = 3 18 def __init__(self, nickname, life_value, aggressivity): 19 self.nickname = nickname 20 self.life_value = life_value 21 self.aggressivity = aggressivity 22 23 def attack(self, enemy): 24 enemy.life_value -= self.aggressivity 25 26 class Garen(Hero): 27 # x = 2 28 pass 29 30 31 class Riven(Hero): 32 pass 33 34 g1 = Garen('alice',80,30) 35 # print(g1.__dict__) 36 # print(g1.nickname,g1.life_value,g1.aggressivity) 37 38 # 继承之后的查找顺序 1.对象自己这找 --> 2.对象所在的类里面找 --> 3.父类里面找 39 # g1.x = 1 40 # print(g1.x) 41 42 43 # 属性查找的小练习 44 class Foo: 45 def f1(self): 46 print('from Foo.f1') 47 def f2(self): 48 print('from Foo.f2') 49 self.f1() #b.f1() 50 class Bar(Foo): 51 d = 1 52 def f1(self): 53 print('from Bar.f1') 54 55 b = Bar() 56 print(b.__dict__) 57 b.f2()
2.派生:子类可以添加自己的 新属性 数据属性 函数属性
查找顺序:1.对象本身--》2.对象所在的类里面找--》3.父类里面找
1 class Hero: 2 def __init__(self, nickname, life_value, aggressivity): 3 self.nickname = nickname 4 self.life_value = life_value 5 self.aggressivity = aggressivity 6 7 def attack(self, enemy): 8 enemy.life_value -= self.aggressivity 9 10 class Garen(Hero): 11 camp = 'Demacia' 12 def attack(self, enemy): 13 print('from Garen Class') 14 15 class Riven(Hero): 16 camp = 'Noxus' 17 18 g1 = Garen('草丛伦',100,30) 19 r1 = Riven('锐雯雯',80,50) 20 # print(g1.__dict__) 21 # print(g1.camp) 22 # g1.attack(r1) 23 # print(r1.life_value) 24 g1.attack(r1)
3.继承的实现原理:python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表
例如:
>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
0.对象本身优先于子类
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如果继承了多个父类,那么属性的查找方式有两种,
分别是:深度优先和广度优先 (本质按列表顺序来) --》只是一种排序的不同方式
python中类分为两种:1.新式类 2.经典类 (py2中)
1.新式类 (py3 --> 只有新式类)
1 #在python2中-》经典类:没有继承object的类,以及它的子类都称之为经典类 ---》深度优先 --> 一条路走到黑 2 # class Foo: 3 # pass 4 # 5 # class Bar(Foo): 6 # pass 7 #在python2中-》新式类:继承object的类,以及它的子类都称之为新式类 8 # class Foo(object): 9 # pass 10 # 11 # class Bar(Foo): 12 # pass 13 # ------------------------------------------------------ 14 #在python3中-》新式类:一个类没有继承object类,默认就继承object---》广度优先 --》从左到右 ,再到继承object的那个类 返回 在从左到右找 15 # class Foo: 16 # pass 17 # print(Foo.__bases__) 18 19 # -------------------------------------------------------- 20 # 验证多继承情况下的属性查找 -- # F D B X E C A 新式类 --》 广度优先 21 class A(object): 22 def test(self): 23 print('from A') 24 25 class X(A): # 注意在这返回了,重新找 因为这里继承了A(object) 26 # def test(self): 27 # print('from X') 28 pass 29 30 class B(X): 31 # def test(self): 32 # print('from B') 33 pass 34 35 class C(A): 36 # def test(self): 37 # print('from C') 38 pass 39 40 41 class D(B): 42 # def test(self): 43 # # print('from D') 44 pass 45 46 class E(C): 47 def test(self): 48 print('from E') 49 pass 50 51 52 class F(D,E): 53 # def test(self): 54 # print('from F') 55 pass 56 # F D B X E C A 57 58 print(F.mro()) 59 # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.X'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>] 60 61 # f = F() 62 # f.test()