• 继承


    继承是面向对象一个非常重要的特性,如果没有继承那就不能称为类。

    当定义一个类时,可以从现有的类继承,新的类称为子类(Sub Class)或派生类,被继承的类称为基类(Base Class),父类或超类(Super Class)。

    派生类定义的语法如下:

    class SubClassName(BaseClassName):
        <statement-1>
        ...
        <statement-Nm>
    

    案例:

    创建一个Animal类用来表示动物,一个Cat类用来表示猫,一个Dog类用来表示狗。

    # 定义一个Animal类表示动物
    class Animal:
        
        name = '动物'
        
        def eat(self):
            print('吃东西')
        
        def drink(self):
            print('喝水')
            
        def sleep(self):
            print('睡觉')
        
        def call(self):
            print('喊叫')
    # 继承
    # 定义一个Cat类继承Animal类表示猫
    class Cat(Animal):
        pass
    # 定义一个Dog类继承Animal类表示狗
    class Dog(Animal):
        pass
    

    这个案例中Cat,Dag继承了Animal类,那么AnimalCat,Dog的父类,Cat,DogAnimal的子类。

    继承的具体体现是子类会继承父类的属性和方法。

    虽然在CatDog类中没有定义任何的属性和方法,但它们自动继承了父类Animal的属性和方法。

    print(dir(Cat))
    

    输出:

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'call', 'drink', 'eat', 'name', 'sleep']
    

    可以在属性中看到call,drink,eat,sleep,name

    cat = Cat()
    print(cat.name)
    cat.eat()
    cat.drink()
    cat.sleep()
    cat.call()
    

    输出:

    动物
    吃东西
    喝水
    睡觉
    喊叫
    

    多继承

    python支持多继承,继承多个父类的子类定义语法如下:

    class SubClassName(Base1,Base2,Base3):
        <statement-1>
        ...
        <statement-Nm>
    

    多继承最简单的情况是,父类之间是无关的,这时搜索从父类所继承的属性的操作是深度优先,从左至右的。因此如果某一属性在SubClassName中未找到,则会在Base1中搜索它,然后(递归地)到Base1的父类中搜索,如果找不到,再到Base2中搜索,依此类推。

    class A:
        name = 'A'
    
    
    class B(A):
        pass
    
    
    class C(B):
        pass
    
    
    class D:
        name = 'D'
    
    
    class E(C, D):
        pass
    
    
    print(E.name)
    

    输出:

    A
    

    上面的代码中类的继承关系为:

    1660123501191

    所以E.name查找的顺序为E,C,B,A,D

    有时候,继承关系比这个更复杂,如果D的父类也是A,那结果就不一样了。

    class A:
        name = 'A'
    
    
    class B(A):
        pass
    
    
    class C(B):
        pass
    
    
    class D(A):
        name = 'D'
    
    
    class E(C, D):
        pass
    
    
    print(E.name)
    

    输出:

    D
    

    python中多继承时类的继承顺序时通过mro算法计算出来的,打印类的__mro__属性,可以返回继承顺序:

    print(E.__mro__)
    

    输出:

    (<class '__main__.E'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)
    

    所以E.name查找的顺序为E,C,B,D,A,最后输出D.

    方法重写

    父辈的东西不一定适合我们,我们可以创造属于自己的世界!嘿嘿。

    父类的属性和方法也不一定完全适合子类,子类可以通过重写覆盖不合适的属性和方法。

    在子类中定义父类中同名的方法和属性会覆盖父类的方法和属性,也叫重写。

    案例:

    在上面的案例中,虽然Cat,Dog类继承了Animal的属性和方法,但是不能区别CatDog,所以大部分方法和属性不合适,需要重写。

    class Cat(Animal):
        name = '猫'
        
        def eat(self):
            print('猫吃鱼')
        
        def call(self):
            print('喵喵叫')
            
            
    class Dog(Animal):
        name = '狗'
        
        def eat(self):
            print('狗吃骨头')
        
        def call(self):
            print('汪汪叫')
    

    分别重写了属性name和方法eatcall

    cat = Cat()
    print(cat.name)
    cat.eat()
    cat.call()
    

    输出:

    猫
    猫吃鱼
    喵喵叫
    
    dog = Dog()
    print(dog.name)
    dog.eat()
    dog.call()
    

    输出:

    狗
    狗吃骨头
    汪汪叫
    
  • 相关阅读:
    HDU 3091 Necklace <<状压dp
    HDU 1074 Doing Homework<<状压dp
    单片机程序设计中的“分层思想”
    单片机的 FIFO循环队列实现
    串口多字节接收
    单片机多字节串口接收(转)
    SD卡应用总结(Fatfs)
    FATFS 初学之 磁盘 I/O接口
    FATFS 初学之 f_gets/ f_putc/ f_puts/ f_printf
    FATFS 初学之 f_chdir/ f_chdrive
  • 原文地址:https://www.cnblogs.com/superwuchaofan/p/16635755.html
Copyright © 2020-2023  润新知