python 面向对象专题(三):基础(三)继承

1. 初识继承

  • 概念:专业角度:如果B类继承A类,B类就称为子类,派生类,A类就称为父类,超类,基类
  • 种类:单继承,多继承
  • 面向对象的三大特征:继承,封装,多态
  • 继承的优点:
    1. 减少重复的代码
    2. 增加类之间的耦合性(不宜多,宜精)
    3. 使代码更清晰,合理化

2. 单继承

  • 定义:只有一个父类

  • 执行父类的属性和方法:

    1.类名执行父类的属性和方法

    2.派生类对象执行父类的属性和方法

    ​ 1.查询顺序:
    ​ 单向不可逆,子类可以使用父类的属性和方法,父类不可以使用子类的属性和方法

    ​ 2.实例化对象时必须执行__init__方法,类中没有,从父类找,父类没有,从object类中找。

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

    方法一:不依赖继承 / 父类.func(对象,其他参数)

    class Animal(object):
        type_name = "动物类"
        def __init__(self,name,sex,age):
            self.name = name
            self.age = age
            self.sex = sex
        def eat(self):
            print("吃东西")
    class Person(Animal):
        def __init__(self,name,sex,age,mind):
            Animal.__init__(self,name,sex,age)
            self.mind = mind
        def eat(self):
            super().eat()
            print(f'{self.name}会吃饭')
    
    p1 = Person("张三","",18,"有思想")
    p1.eat()

     

    方法二:依赖继承 / 利用super

    class Aniaml(object):
       type_name = '动物类'
       def __init__(self,name,sex,age):
               self.name = name
               self.age = age
               self.sex = sex
       def eat(self):
           print('吃东西')
    class Person(Aniaml):
       def __init__(self,name,sex,age,mind):
    {super(Person,self).__init__(name,sex,age)} (完整写法) 
           super().__init__(name,sex,age)
           self.mind = mind
       def eat(self):
           super().eat()
           print('%s 吃饭'%self.name)
    class Cat(Aniaml):
       pass
    p1 = Person('张三','',18,'有思想')
    print(p1.__dict__)
    
    # 利用super,super().func(参数)
    # super.__init__执行父类
    # 执行父类的__init__方法,重构父类方法.

    单继承应用示例:

    class Base:
        def __init__(self,num):
            self.num = num
        def func1(self):
            print(self.num)
            self.func2()
        def func2(self):
            print(222,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
    222 1
    2
    222 2
    3
    222 3

     

  • 单继承总结:

    1. 面向对象中super的作用:

    ​ super().func(参数) 重构父类的方法,严格按照对象从属类的mro顺序执行

3. 多继承

  • Python类分为两种:
    经典类:不继承object类,深度优先原则,深度优先.从左至右,深度优先.
    新式类:继承object类,mro(C3)算法(新式类查询顺序)

  • Python2x:Python2.2之前都是经典类,Python2.2之后,经典类和新式类共存
    Python3x:全都是新式类,如果基类谁都不继承,那这个类会默认继承object类

  • 新式类推导示例:

    class O:
        name = '张三'
    
    class D(O):
        pass
    
    class E(O):
        name = '李四'
        # pass
    class F(O):
        name = '王五'
    
    class B(D,E):
        pass
    
    class C(E,F):
        pass
    
    class A(B,C):
        pass
    
    obj = A()
    print(obj.name)
    
    # mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
    # mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C])
    
    '''
    mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C])
    
    mro(B(D,E)) = [B] + merge(mro(D),mro(E),[D,E])
    
    mro(B(D,E)) = [B] + merge([D,O],[E,O],[D,E])
    mro(B(D,E)) = [B,D] + merge([O],[E,O],[E])
    mro(B(D,E)) = [B,D,E] + merge([O],[O])
    mro(B(D,E)) = [B,D,E,O]
    
    mro(C) = [C,E,F,O]
    
    mro(A(B,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,O] 
    '''
    
    # print(A.mro())

     

  • 经典类推导示例:见下面示例

4. 总结

  1. 类的静态属性,如果指向一个可变数据类型,对象或者类名都可以给这个可变数据类型内部增,删,改,查(不可以对其整体增,删,改,查)

    示例代码:

    class A:
        name = []
    p1 = A()
    p2 = A()
    p1.name.append(1)
    # p1.name,p2.name,A.name 分别是什么?
    # 结果:[1],[1],[1]

     

  2. 新式类,经典类示例

    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
    # 如果这是经典类,请写出他的继承顺序。
    KHEBACFDIG
    
    # 如果这是新式类,请写出他的继承顺序,并写出具体过程。
    KHEBIFCGDA

     

posted @ 2020-05-09 16:32  秋华  阅读(277)  评论(0编辑  收藏  举报