Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)

mac2022-06-30  64

Python进阶(十五)----面向对象之~继承

一丶面向对象的三大特性:封装,继承,多态

二丶什么是继承

# 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # b类或者b对象 能够使用 a类的所有属性和方法 # 为什么要有继承 由子类继承父类,从而完成了对子类功能的扩展 #第一: 子类对父类的继承是全部的公有和受保护的继承,这使得子类可能继承了对子类无用甚至有害的父类的方法。换句话说,子类只希望继承父类的一部分方法,怎么办? #第二: 实际的对象千变万化,如果每一类的对象都有他们自己的类,尽管这些类都继承了他们的父类,但有些时候还是会造成类的无限膨胀。 #第三: 继承的子类,实际上需要编译期确定下来,这满足不了需要在运行内才能确定对象的情况。而组合却可以比继承灵活得多,可以在运行期才决定某个对象。 #摘自: hivon博主 # 总结: # 对类的功能的扩展,要多用组合,少用继承。

三丶继承的优缺点

#优点: #1.节省代码, 2.增强耦合性 , 3. 代码规范化 , 4 .重构父类方法 #缺点: # 继承关系会造成 高耦合性

转一篇关于 继承 优缺点的文章

四丶单继承

## 单继承 class Animal: live = '活着' def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def eat(self): print('in eat function') class Person(Animal): pass ### 1. 子类以及对象 可以调用父类的方法和属性 print(Person.live) # 子类名.父类中的属性 , 查看或获取父类中的变量 Person.eat('d') # 子类名.父类中的方法,调用父类的方法 print(Person.__dict__) # 查看 子类中 存在的属性 ### 2. 从对象执行父类的一切. # 实例化对象一定一定会执行三件事. 一定会执行__init__ p1 = Person('ly', '男', '21') print(p1.live) # 对象调用 类中的属性 p1.eat() # 对象 调用类中的方法 print(p1.__dict__) # 查看 p1对象的属性 Person.live = 'xxx' print(Person.live) # 注意: 子类以及子类对象,只能调用父类的属性以及方法 , 不能操作增删改 ## 单继承super的使用 , class Animal: live = '活着' def __init__(self, name, sex, age): # self 接收的 p1 对象内存空间,给p1封装属性 self.name = name self.sex = sex self.age = age def eat(self): print('in 父类 eat function') class Person(Animal): def __init__(self,name,age,sex,hobby): # 给p1 封装 hobby属性 # Animal.__init__(self,name,age,sex) # 执行父类的 __init__方法 , self 是当前p1 对 . # super(Person, self).__init__(name,sex,age) super().__init__(name,sex,age) #执行父类 __init__方法 self.hobby=hobby def eat(self): print('子类吃') super().eat() p1=Person('ly','33','人妖','服务') p1.eat() print(p1.__dict__) #打印p1对象中的属性, 父类定义的属性, 和子类自定义的属性 都存在

五丶多继承

python 2.2 之前: 都是经典类

class A: # 经典类 不继承object类 pass

python 2.2 直至 python2.7 之间存在两种类型:经典类,新式类

  经典类:

      基类不继承object ,查询规则:依靠深度优先(先深入继承树左侧查找,然后再返回,开始查找右侧) ​

  新式类:

      必须继承object , 查询规则: MRO算法

class A: # 经典类 pass class B(object): #新式类 pass

python3x 只有新式类

class B(object): # 新式类 , (object) 默认可以不写 继承object类 pass ### 多继承案例 class ShenXian: # 神仙 def fei(self): print("神仙都会⻜") class Monkey: # 猴 def chitao(self): print("猴⼦喜欢吃桃⼦") class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴 pass sxz = SunWukong() # 孙悟空 sxz.chitao() # 会吃桃⼦ sxz.fei() # 会⻜

​ 多继承的难点就是继承顺序的问题

       MRO算法:

#### 新式类 继承关系的运算 ### mro算法 # 公式: # mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] ) # mro(Foo(H,G)) = [Foo] + merge(mro(H), mro(G),[H,G]) # 表头: #   列表的第一个元素 # 表尾: #   列表中表头以外的元素集合(可以为空) # 表头,表尾 # [A,B,C] : 表头: A 表尾: [B,C] # [A] : 表头: A 表尾: [] # +操作 # [A] + [B] = [A, B] class O: pass class D(O): pass class E(O): pass class F(O): pass class B(D,E): pass class C(E,F): pass class A(B,C): pass a = A() #### 方式一 套用公式 ''' mro(A(B,C))=[A] + merge(mro(B) , mro(C)), [B,C] # merge(mro(B) , mro(C)) 放到下面拆解了 =[A] + merge( [B,D,E,O] , [C,E,F,O] ) ,[B,C] =[A,B] + merge([D,E,O],[C,E,F,O]),[C] =[A,B,D] + merge([E,O],[C,E,F,O]),[C] =[A,B,D,C,] + merge([E,O],[E,F,O]) =[A,B,D,C,E] + merge([O],[F,O]) =[A,B,D,C,E,F] + merge([O]) =[A,B,D,C,E,F,O] mro(B(D,E))=[B] + merge(mro(D),mro(E)), [D,E] # C3算法, merge操作是C3算法的核心。 =[B] + merge([D]+[O],[O] ,[E]+[O],[O]),[D,E] # 公式拆解, =[B] + merge([D,O],[E,O]),[D,E] =[B,D] + merge([O],[E,O]),[E] =[B,D,E] + merge([O]) =[B,D,E,O] mro(C[E,F])=[C] + merge(mro(E),mro(F)),[E,F] =[C] + merge([E]+megre([O]),[F]+megre([O])),[E,F] =[C] + merge([E,O],[F,O]) ,[E,F] =[C,E] + merge([O],[F,O]),[F] =[C,E,F] + merge([O],[O]) =[C,E,F,O] ''' #### 方式二 使用 mro() print(A.mro()) # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.F'>, <class '__main__.O'>, <class 'object'>]

转载于:https://www.cnblogs.com/dengl/p/11158348.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)