• python---面对对象的三大特征


    一、三大特征

      面对对象的三大特征:继承、多态和封装,继承在面向对象类的创建中非常常见。

    1、继承

      为什么会有继承,当我们要创建一个新类的时候,发现他有很多属性或者反法都和我们另一个类的方法相同,这时我们就可以用继承。Python中继承分为单继承和多继承。

    class Animal:
        def __init__(self):
            self.name = name
            self.kind = kind
            self.food = food
            self.language = language
        def yell(self):
            print('%s叫'%self.language)
        def eat(self):
            print('吃%s'%self.foode)
        def drink(self):
            print('喝水')

    上面已经有了一个Animal类,属性有名字、类型、食物、语言属性,方法有叫,吃,喝水.这时我叫生成一个狗类和猫类,你会发现在狗猫类中也有这些行为和方法这样我们就可以用到继承

    class Animal:
        def __init__(self,name,kind,food,language):
            self.name = name
            self.king = kind
            self.food = food
            self.language = language
        def yell(self):
            print('%s叫'%self.language)
        def eat(self):
            print('吃%s'%self.food)
        def drink(self):
            print('喝水')
    
    class Cat(Animal):
        def look_after(self):
            print('看家')
    
    class Dog(Animal):
        def catch_mouse(self):
            print('抓老鼠')
    
    Tom = Cat('汤姆','家猫','猫粮','喵喵')
    Tom.yell()  #喵喵叫
    Tom.eat()  #吃猫粮
    
    jd = Dog('京东狗','白狗','狗粮','汪汪')
    jd.yell()  #汪汪叫
    jd.eat()  #吃狗粮

    Cat(Animale)这就是继承的语法,在括号里面的叫做父类或者超类基累,而Cat叫做派生类,派生类可以调用父类的所有方法以及属性,同时遵循以下规则:

    子类可以使用父类中的名字(变量和方法)

    子类在父类的基础上又新创建了自己需要的方法和属性

    父类有的子类没有 - 子类对象直接调用 就会直接执行父类的方法

    父类有的子类也有 - 子类对象调用 直接执行子类中的方法

    class Animal:
        def __init__(self,name,kind,food,language):
            self.name = name
            self.king = kind
            self.food = food
            self.language = language
        def yell(self):
            print('%s叫'%self.language)
        def eat(self):
            print('吃%s'%self.food)
        def drink(self):
            print('喝水')
    
    class Cat(Animal):
        def look_after(self):
            print('看家')
        def yell(self):
            print('子类方法')
    
    class Dog(Animal):
        def catch_mouse(self):
            print('抓老鼠')
    
    Tom = Cat('汤姆','家猫','猫粮','喵喵')
    Tom.catch_mouse()  # catch_mouse方法只有子类中有调用子类方法
    Tom.yell()   #yell方法在子类和父类中都有,会优先找子类的
    Tom.eat()  #子类中没有eat方法,调用父类的eat方法

    二、派生

      前面讲到子类可以调用父类的属性,也就是父类中init的特征属性,那么子类可以有自己的特征属性吗,当然是可以的。需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以子类自己的特征属性为主了。

    class Animal:
        def __init__(self,name,kind,food,language):
            self.name = name
            self.kind = kind
            self.language = language
        def eat(self):
            print('吃%s'%self.food)
    
    class Cat(Animal):
        def __init__(self,eyecolor):
            self.eyecolor = eyecolor
    
    Tom = Cat('蓝色')
    print(Tom.eyecolor)    #蓝色
    print(Tom.name)    #报错

    这时大家可能会问为什么Tom.name会报错呢,还是遵循这样的原则:父类有的子类也有 - 子类对象调用 直接执行子类中的方法  

    大家注意 __init()__这个函数是不是子类和父类在都有,这时子类会优先执行子类自己的__init()__方法,这样子类的属性就只有eyecolor而已你去调用对象Tom去找时也只会在子类自己的__init()方法中去找,所以这样子类的属性中就只有子类自己的属性了。

    其实子类自己初始化__init__的时候将父类的属性添加到子类的属性中去就可以了:

    class Animal:
        def __init__(self,name,kind,food,language):
            self.name = name
            self.kind = kind
            self.language = language
        def eat(self):
            print('吃%s'%self.food)
    
    class Cat(Animal):
        def __init__(self,name,kind,food,language,eyecolor):
            self.eyecolor = eyecolor
            super().__init__(name,kind,food,language)    
        # super().__init__(name,kind,food,language)
        #或者替换成Animal.__init__(self,name,kind,food,language)
    
    Tom = Cat('汤姆','家猫','猫粮','喵喵','蓝色')
    print(Tom.name)    #汤姆
    但需记得的是将父类的属性添加进来后,子类实例化的参数也要随着属性的增多添加。
    总结;

     当子类当中有要被调用的方法的时候,子类的对象会直接选择子类中的方法、变量,父类中的方法不会被自动执行

     如果我们既想要执行子类的方法,也想要执行父类的方法,那么需要在子类的方法中调用父类的方法:
     父类名.方法名(self,...)
     super().方法名(...)
    帮助我们在子类中调用父类中的同名方法

    三、多继承

      多继承,在python中一个子集是可以继承多个父级的

    
    
    class Animal:
    def __init__(self,name):
    self.name = name
    def fly(self):
    print('%s在飞'%self.name)
    def walk(self):
    print('%s在走路'%self.name)
    def swim(self):
    print('%s在游泳'%self.name)

    obj = Animal('狗')
    obj.walk()  #狗在走路
    obj.swim()  #狗在游泳
    obj.fly()    #狗在飞
    obj = Animal('鸟')
    obj.fly()  #鸟在飞

    看样看出实例化出来的对象可以调用父类所有的方法,连狗都能飞了!这样肯定不行,那么如何让狗调用不了飞的方法呢,其实我们可以更具体,将飞的方法变成一个类,走的也变成一个类,而动物类只负责生成属性:

    class Animal:
        def __init__(self,name):
            self.name = name
    
    class FlyAnimal(Animal):
        def fly(self):
            print('%s在飞' % self.name)
    class WalkAnimal(Animal):
        def walk(self):
            print('%s在走路'%self.name)
    class SwimAnimal(Animal):
        def swim(self):
            print('%s在游泳'%self.name)
    
    class Tiger(SwimAnimal,WalkAnimal):
        pass
    
    class Swan(SwimAnimal,WalkAnimal,FlyAnimal):
        pass
    
    class Parrot(FlyAnimal,WalkAnimal):
        def talk(self):
            print('%s说话了'%self.name)
    
    swan = Swan('天鹅')
    swan.fly()
    swan.walk()

    继承小结:

      

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

    >>> F.mro() #等同于F.__mro__
    [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

    为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
    而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
    1.子类会先于父类被检查
    2.多个父类会根据它们在列表中的顺序被检查
    3.如果对下一个类存在两个合法的选择,选择第一个父类

  • 相关阅读:
    IIS7.5应用程序池集成模式和经典模式的区别介绍(转)
    (转)Extjs4 展示图片与图片的更新
    webservices发布后远程无法调试的解决方法
    .Net通过OleDb方式读取Excel
    1000个JQuery插件(转载)
    2006年中科大计算机考研复试机试题
    2. 最好使用C++转型操作符
    16. 谨记8020法则
    英语阅读理解中表示作者态度的词汇汇总
    5. 对定制的“类型转换函数”保持警觉
  • 原文地址:https://www.cnblogs.com/Kingfan1993/p/9548464.html
Copyright © 2020-2023  润新知