zoukankan      html  css  js  c++  java
  • python面向对象 : 继承

    一. 初识继承

      继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类.

      当我们在定义多个类的时候,发现要用到相同的方法或变量,如果每个类都要写相同的方法和变量,那么代码就会重复,为了减少代码,可以用继承来解决.

    # 三个类中都有相同的参数,造成代码重复
    
    class Person:
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age
    
    class Cat:
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age
    
    class Dog:
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age

      用继承的思想来做

    class Animal:
        animal = '动物'
        def __init__(self, name, sex, age):
            self.name = name
            self.sex = sex
            self.age = age
    
        def hobby(self):
            print('%s喜欢吃' % self.name)
    
    class Person(Animal):  #继承Animal类
        pass
    class Cat(Animal):
        pass
    class Dog(Animal):
        pass
    
    print(Person.animal)  #动物  类名可以访问父类所有内容
    p = Person('jack', '', 25)
    p.hobby()  #jack喜欢吃
    # 子类以及子类实例化的对象 可以访问父类的任何方法或变量.先从本类中找hobby方法,找不到则从父类里找
    既要执行子类的方法,又要执行父类的方法? 有两种解决方法.
    1,Animal.__init__(self, name, sex, age)
    2,super().__init__(name,sex,age)
    class Animal:
        def __init__(self, name, sex, age):
            self.name = name
            self.sex = sex
            self.age = age
    
        def eat(self):
            print('%s会吃' % self.name)
    
        def drink(self):
            print('%s会喝' % self.name)
    
    
    class Bird(Animal):
        def __init__(self, name, sex, age, wing):
            # super().__init__(name, sex, age )  #自动把self传给父类
            Animal.__init__(self, name, sex, age)
            self.wing = wing
    
        def egg(self):
            print('鸡会下蛋')
    
        def eat(self):  #本类含有和弗雷相同的方法名
            super().drink()  #用super()调用父类的方法
            print('鸟会吃虫子')
    
    
    b = Bird('', '', 30, '翅膀')
    print(b.__dict__)  # {'name': '鸟', 'sex': '公', 'age': 30, 'wing': '翅膀'}
    b.eat()  
    # 鸟会喝    #执行父类的eat方法
    # 鸟会吃虫子   #执行本类的eat方法

    二. 继承的进

    1. 单继承和多继承

    class A:
        pass
    class B(A):  #单继承
        pass
    class C(A):
        pass
    class D(B,C):  #多继承
        pass

    2. 经典类, 新式类 

      新式类: 凡是继承object类都是新式类. python3x 所有的类都是新式类,因为python3x中的类都默认继承object.

      经典类: 不继承object类都是经典类, python2x:(既有新式类,又有经典类) 所有的类默认都不继承object类,所有的类默认都是经典类.你可以让其继承      object.

       单继承: 新式类,经典类查询顺序一样.
       多继承继承顺序(讨论的是继承两个类):
    新式类: 遵循广度优先 : 一条路走到倒数第二级,判断,如果其他路能走到终点,则返回走另一条路.如果不能,则走到终点. 可以用mro()来查询继承顺序.
           经典类: 遵循深度优先 : 一条路走到底.
    class A:
        def func(self):
            print('IN A')
    
    class B(A):
        # pass
        def func(self):
            print('IN B')
    
    class C(A):
        # pass
        def func(self):
            print('IN C')
    
    class D(B):
        # pass
        def func(self):
            print('IN D')
    
    class E(C):
        def func(self):
            print('IN E')
    
    class F(D,E):
        # pass
        def func(self):
            print('IN F')
    
    f1 = F()
    f1.func()  #IN F
    
    print(F.mro())  # 查询类的继承顺序
    # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, 
    # <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

     3. 多继承原理: MRO_C算法

     mro():  查询类的继承顺序.  代码和步骤如下:
    class H:
        pass
    
    
    class G(H):
        pass
    
    
    class F(H):
        pass
    
    
    class E(G):
        pass
    
    
    class D(F):
        pass
    
    
    class C(E):
        pass
    
    
    class B(D):
        pass
    
    
    class A(B, C, D):
        pass
    
    
    print(A.mro())
    
    '''
    首先找到A继承的三个类的深度继承顺序,放到一个列表中
    
    B   [B,D,F,H]
    C   [C,E,G,H]
    D   [D,F,H]
    
    每个列表的第一个元素为头部,其它位置元素都为尾部,从第一个列表的头部开始找,找其他列表中尾部是否含有
    这个类名,如果没有,提取出来放到一个列表中,如果有,找下一个列表的头部,循环下去
    只要提取来一个,我们就从第一个列表的头部接着重复上面的操作.
    
    A   [A][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]  A #找到第一个列表的头A,其他列表尾部没有A,把A取出来,如果其他列表的头部有A则剔除
        [][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]   B
        [][D,F,H] [C,E,G,H] [D,F,H] [C,D]       C
        [][D,F,H] [E,G,H] [D,F,H] [D]           D
        [][F,H] [E,G,H] [F,H] []                F 
        [][H] [E,G,H] [H] []                    E #找到第一个列表的头部H,但是其他列表尾部有H,所以跳过这个列表,去下一个列表取头部
        [][H] [G,H] [H] []                      G
        [][H] [H] [H] []                        H
        [][] [] [] [] 
        lst = [A,B,C,D,F,E,G,H] 
    '''
    
    
    class F:
        pass
    
    
    class E:
        pass
    
    
    class D:
        pass
    
    
    class C(D, F):
        pass
    
    
    class B(E, D):
        pass
    
    
    class A(B, C):
        pass
    
    
    print(A.mro())
    '''
    首先找到A继承的两个类的深度继承顺序
    把B作为子类,找出B类的查询顺序
    
    B   [B] [E] [D] [E,D]  B  
        [] [E] [D] [E,D]   E
        [] [] [D] [D]      D
        [] [] [] []
        lst = [B,E,D]
    把C作为子类,找出C类的查询顺序
    
    C   [C] [D] [F] [D,F]  C
        [] [D] [F] [D,F]   D
        [] [] [F] [F]      F
        [] [] [] []       
        lst = [C,D,F]
    
    A   [A] [B,E,D] [C,D,F] [B,C]  A
        [] [B,E,D] [C,D,F] [B,C]   B 
        [] [E,D] [C,D,F] [C]       E
        [] [D] [C,D,F] [C]         C
        [] [D] [D,F] []            D
        [] [] [F] []               F
        [] [] [] []
        lSt = [A,B,E,C,D,F]    
    '''




    
    
     
    
    
    
     
    无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
  • 相关阅读:
    Java工程代码开发规范总结
    MySQL5.7 JSON字段性能测试
    Forest v1.5.12 发布,声明式 HTTP 框架,已超过 1.6k star
    HTTP基础系列之:一文搞懂URL
    近1000 star,Forest 1.5.0 正式版发布
    我的开源项目在五个月内超过了 600 star
    我的开源经历:为了方便处理三方 HTTP 接口而写的 Java 框架
    【约瑟夫环】C语言数组法+java循环链表法
    UNICODE编码 特殊符号
    swift3.0 保存图片到本地,申请权限
  • 原文地址:https://www.cnblogs.com/huangqihui/p/9367520.html
Copyright © 2011-2022 走看看