• 继承


    继承--inheritance

    面向对象的的三大特征:继承、封装、多态。

    1. 面向对象继承:

    ​ 如果B类继承A类,B类就称为子类、派生类,A类就称为父类、超类、基类。

    继承的优点:

    	1. 减少重复代码;
    	2. 增加了类的耦合性;
    	3. 使代码清晰、流畅。
    

    2. 单继承

    2.1 类名执行父类的属性、方法

    # 类名.属性/方法
    

    2.2 子类对象执行父类的属性、方法

    # 实例化子类对象
    # 对象.属性/方法
    
    class Animal:
    
        live = '有生命的'
        def __init__(self, name, sex, age):
            self.name = name
            self.age = age
            self.sex = sex
    
        def eat(self):
            print("都需进食")
    
    class Human(Animal):
        # pass
        body = '有头'
    
    print(Human.live)
    Human.eat(1)
    
    obj = Human('meet', '男', 30)
    print(obj.live)
    print(obj.body)
    obj.eat()
    

    2.3 执行顺序

    # 单项不可逆:实例化对象时必须执行__init__方法,如果子类没有,从父类找,父类没有,从object类中找。
    # 如果是 对象.方法,会先从自己的类找方法,自己类没有,才能执行父类中的方法。
    

    2.4 既要执行子类的方法,又要执行父类的方法

    # 当子类中也有__init__方法时,如何能够调用父类的方法?
    
    # 方法一: 不依赖继承
    # 在子类的__init__中调用父类__init__函数,并且将相应的参数传入。  
    #  父类名.__init__(self(对象),其他参数)
    
    class Animal:
    
        live = '有生命的'
        def __init__(self, name, sex, age):
            self.name = name
            self.age = age
            self.sex = sex
    
        def eat(self):
            print("动物都需进食")
    
    class Human:   # 不依赖继承
    
        body = '有头'
        def __init__(self, name, sex, age, hobby):
            Animal.__init__(self, name, sex, age)
            self.hobby = hobby
    
    obj = Human("meet", "男", 20, "旅游")
    print(obj.__dict__)
    
    # 方法二: 依赖继承
    # 在子类中,使用super实现
    super(类名,self).__init__(参数)    #完整写法
    super().__init__(参数)       # 执行父类的__init__方法,重构父类的方法。
    super().方法名()
    
    class Animal:
    
        live = '有生命的'
        def __init__(self, name, sex, age):
            self.name = name
            self.age = age
            self.sex = sex
    
        def eat(self):
            print("动物都需进食")
    
    class Human(Animal):   # 依赖继承
        
        body = '有头'
        def __init__(self, name, sex, age, hobby):
            # super(Human,self).__init__(name,sex,age)
            super().__init__(name,sex,age)
            self.hobby = hobby
    
        def eat(self):
            super().eat()
            print(f'{self.name}都需吃饭')
    
    obj = Human("meet", "男", 20, "旅游")
    print(obj.__dict__)
    obj.eat()
    

    2.5 单继承执行顺序练习题

    # 1
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
    
    class Foo(Base):
        pass
    obj = Foo(123)
    obj.func1()  # 123 先执行__init__;然后调用Base中的func1  
    
    # 2      
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
    class Foo(Base):
        def func1(self):
            print("Foo. func1", self.num)
    obj = Foo(123)
    obj.func1() # Foo. func1 123 运⾏的是Foo中的func1       
    
    # 3
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
            self.func2()
        def func2(self):
            print("Base.func2")
    class Foo(Base):
        def func2(self):
        print("Foo.func2")
    obj = Foo(123)
    obj.func1() # 123 Foo.func2 	func1是Base中的 func2是⼦类中的 
    
    # 4
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
            self.func2()
        def func2(self):
            print(111, self.num)
    class Foo(Base):
        def func2(self):
            print(222, self.num)
    lst = [Base(1), Base(2), Foo(3)]
    for obj in lst:
        obj.func2() # 111 1 | 111 2 | 222 3
    
    # 5
    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
            self.func2()
        def func2(self):
            print(111, self.num)
    class Foo(Base):
        def func2(self):
            print(222, self.num)
    lst = [Base(1), Base(2), Foo(3)]
    for obj in lst:
    	obj.func1()    # 1 111 1 | 2 111 2 | 3 222 3
    

    3. 多继承

    python的类分为两种:
    	python2x:在python2.2之前都是经典类,python2.2后,经典类与新式类共存。
        python3x:全部都是新式类。
    
    class ShenXian: # 神仙
        def fei(self):
            print("神仙都会⻜")
    class Monkey: # 猴
        def chitao(self):
            print("猴⼦喜欢吃桃⼦")
    class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴
        pass
    sxz = SunWukong() # 孙悟空
    sxz.chitao() # 会吃桃⼦
    sxz.fei() # 会⻜
    

    3.1 经典类

    	不继承object类,深度优先原则(从左往右,找到底)
    

    类的MRO: Foo-> H -> G -> F -> E -> D -> B -> A -> C.

    ​ 从头开始. 从左往右. ⼀条路跑到头, 然后回头. 继续⼀条路跑到头. 就是经典类的MRO算法.

    3.2 新式类

    	继承object,mro算法(C3)
    
    mro(Child(Base1,Base2))=[ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
    (其中Child继承自Base1, Base2)
    
    # 如计算merge( [E,O], [C,E,F,O], [C] )
    有三个列表 :  ①      ②          ③
    1.merge不为空,取出第一个列表列表①的表头E,进行判断                各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
    2.取出列表②的表头C,进行判断
       C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除c
    merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
    							  = [C,E] + merge([0],[F,0])
    							  = [C,E,F] + merge([0],[0])
    							  = [C,E,F,O]
    							  
    
    表头:
      列表的第一个元素
    表尾: 
      列表中表头以外的元素集合(可以为空)
    示例 
      列表:[A, B, C] 
      表头是A,表尾是B和C
    
    print(子类.mro())    # 查看子类的执行、查找顺序
    
    class A:
        pass
    class B(A):
        pass
    class C(A):
        pass
    class D(A):
        pass
    class E(B, C):
        pass
    class F(C, D):
        pass
    class G(D):
        pass
    class H(E, F):
        pass
    class I(F, G):
        pass
    class K(H, I):
        pass
    
    # print(K.mro())
    
    如果这是经典类,请写出他的继承顺序。
    K->H->E->B->A->C->F->D->I->G
    
    如果这是新式类,请写出他的继承顺序,并写出具体过程。
    
    """
    mro(Child(Base1,Base2))=[ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
    mro(K(H,I)) = [K] + merge(mro(H),mro(I),[H,I])
    mro(H) = mro(H(E,F))
           = [H] + merga(mro(E),mro(F))
           
           = [H] + merga([E,B,C,A],[F,C,D,A],[E,F])
           = [H,E] + merga([B,C,A],[F,C,D,A],[F])
           = [H,E,B] + merga([C,A],[F,C,D,A],[F])
           = [H,E,B,F] + merga([C,A],[C,D,A])
           = [H,E,B,F,C,D,A]
           
    mro(E) = mro(E(B,C))
           = [E] + merga(mro(B),mro(C))
           = [E] + merga([B,A],[C,A],[B,C])
           = [E,B,C,A]
    mro(F) = mro(F(C,D))
           = [F] + merga(mro(C),mro(D))
           = [F] + merga([C,A],[D,A],[C,D])
           = [F,C,D,A]
           
    mro(B) = mro(B(A))
           = [B,A]
    mro(C) = mro(C(A))
           = [C,A]
    mro(D) = mro(D(A))
           = [D,A]
    
    mro(I) = mro(I(F,G))
           = [I] + merga(mro(F),mro(G),[F,G])
           
           = [I] + merga([F,C,D,A],[G,D,A],[F,G])
           = [I,F] + merga([C,D,A],[G,D,A],[G])
           = [I,F,C] + merga([D,A],[G,D,A],[G])
           = [I,F,C,G,D,A] 
           
    mro(G) = mro(G(D))
           = [G,D,A]
    
    总式:       
    mro(K(H,I)) = [K] + merga([H,E,B,F,C,D,A], [I,F,C,G,D,A], [H,I])
                = [K,H] + merga([E,B,F,C,D,A], [I,F,C,G,D,A], [I])  
                = [K,H,E] + merga([B,F,C,D,A], [I,F,C,G,D,A],[I])
                = [K,H,E,B] + merga([F,C,D,A], [I,F,C,G,D,A],[I]) 
                = [K,H,E,B,I] + merga([F,C,D,A], [F,C,G,D,A]) 
                = [K,H,E,B,I,F,C,G,D,A] 
    
    """
    
  • 相关阅读:
    fastadmin中curd生成的表单将数字展示为文字
    fastadmin弹窗效果表单
    fastadmin 框架中图片点击放大
    linux vi 编辑文件常用快捷键
    mysql 数据库执行创建索引语句异常 Specified key was too long; max key length is 767 bytes
    eclipse 版本库信息存储错误,导致每次更新提交信息总弹出要输入账号密码问题 解决
    外国域名无法访问 metricbeat.docker.yml 无法下载问题解决
    ELK elasticsearch docker 多台服务器集群
    zipkin 服务跟踪
    多线程 采用spring线程池ThreadPoolTaskExecutor提高程序处理能力 笔记
  • 原文地址:https://www.cnblogs.com/liwenhu/p/11401544.html
Copyright © 2020-2023  润新知