• Day17 python基础---面向对象三大特性---继承


    一,继承和抽象概念

      1.抽象:即抽取类似或者比较像的部分。抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类。

         抽象分成两个层次:

        1)将奥巴马和梅西这俩对象比较像的部分抽取成类;

        2)将人,猪,狗这三个类比较像的部分抽取成父类。

            2.继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

         

    二,单继承

           1.语法:父类,子类

              父类/超类/基类

              子类/派生类

      2.继承与重用

               父类所有的属性和方法都可以被子类使用

    class Animal:  #父类/超类/基类 
        def __init__(self,name,kind,food,language):
            self.name = name
            self.kind = kind
            self.food = food
            self.language = language
    
        def yell(self):
            print('%s叫'%self.language)
        def eat(self):
            print('%s吃%s'%(self.name,self.food))
        def drink(self):
            print('%s喝'%self.name)
    
    class Cat(Animal):  #子类/派生类 
        def catch(self):
            print('%s抓老鼠'%self.name)
    
    class Dog(Animal):  #子类/派生类 
        def look_after_house(self):
            print('%s看家'%self.name)
    
    # 继承与重用 -  父类中所有的属性和方法都可以被子类使用了
    阿猫 = Cat('阿猫','橘猫','猫粮','喵喵')
    阿狗 = Dog('阿狗','二哈','狗粮','汪汪')
    print(阿猫.name)
    阿猫.drink()
    阿猫.eat()
    阿猫.catch()
    阿猫.yell()

      3.继承与派生

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

                  1.父类有的子类没有:子类对象直接调用,就会直接执行父类的方法

                  2.父类有的子类也有:子类对象调用,直接执行子类中的方法,若在子类中使用父类的属性和方法:父类名、super()去调用

    class Cat(Animal):   #Animal的派生类
        def __init__(self,name,kind,food,language,eye_color):
            self.eye_color = eye_color   #派生属性
            Animal.__init__(self,name,kind,food,language)
            #super().__init__(name,kind,food,language)
        def catch(self):    #派生方法
            print('%s抓老鼠'%self.name)
        def eat(self):    # 不仅执行了父类中的基础功能,还完成了特殊的功能
            Animal.eat(self)
            #super().eat()
            self.weight = 10
    # 当子类当中有要被调用的方法的时候,子类的对象会直接选择子类中的方法、变量,父类中的方法不会被自动执行
    # 如果我们既想要执行子类的方法,也想要执行父类的方法,那么需要在子类的方法中调用父类的方法:
    #   父类名.方法名(self,...)
    #   super().方法名(...)
    #   帮助我们在子类中调用父类中的同名方法
    # 面向对象特性之继承--面试题
    #当self去调用某个方法的时候,不要看self在哪个类里,要看self到底是谁
    class Foo: def __init__(self): self.func() def func(self): print('in Foo') class Son(Foo): def func(self): print('in Son') s1 = Son() ################## class Foo: Country = 'China' def func(self): print(self.Country) class Son(Foo): Country = 'English' def func(self): # 走这个方法 print(self.Country) s = Son() s.func() #################### class Foo: Country = 'China' def func(self): # 走这个方法 print(self.Country) class Son(Foo): Country = 'English' s = Son() s.func() # English ######################### class Foo: Country = 'China' def func(self): print(self.Country) class Son(Foo):pass s = Son() s.func() # 'China'

      4.规范的编程模式:抽象类

            抽象类的概念:

       1.抽象类是一个规范,它基本不会实现什么具体功能,抽象类是不能被实例化的

             2.工作中,有的公司源码有使用抽象类开发的规则,在多人开发,复杂的需求,后期的扩展的场景中,使用抽象类来帮助我们完成规范

    # 抽象类语法
            # from abc import ABCMeta,abstractmethod
            # 在这个类创建的时候指定 metaclass = ABCMeta
            # 在你希望子类实现的方法上加上一个 @abstractmethod装饰器
    
    #抽象类的使用
            # 继承这个类
            # 必须实现这个类(子类创建同名的方法)中被@abstractmethod装饰器装饰的方法
    from  abc import ABCMeta,abstractmethod
    
    class Payment(metaclass=ABCMeta):   # 模板的功能
        @abstractmethod       # abstractmethod是一个装饰器,放在函数/类的上一行
        def pay(self):pass   #该抽象类的子类,都必须实现父类的方法,否则报错
    
    class Alipay(Payment):
        def pay(self,money):
            print('使用支付宝支付了%d'%money)
    
    class wechatpay(Payment):
        def pay(self,money):
            print('使用支付宝支付了%d'%money)
    
    def pay(obj,money):#构造函数存入对象和参数,自动调用类的方法
        obj.pay(money)
    
    #TypeError: Can't instantiate abstract class Payment with abstract methods pay
    #p = Payment()  #抽象类实例化会报错
    a = Alipay()
    w = wechatpay()
    pay(a,100)
    pay(w,150)
    #所有的对象的type都是创造这个对象类
    class A:pass
    obj = A()
    type(obj) is A
    #所有没有指定metaclass的类的type都是type
    #如果指定了metaclass,那么这个类的type就是指定的metaclass的值
    #类也是被创造出来的,type是创造类的机制,即元类是创造类的机制
    #例:补全func:
    #     - dir方法能够得到当前文件中的所有成员
    #     - 获取handler中名字叫Base的成员
    #     - 检查其他成员是否是Base类的子类(不包含Base),如果是则创建对象并添加到objs列表中。
    
    
    class Base(object):pass
    
    class F1(Base):pass
    
    class F2(Base):pass
    
    class F3(F2):pass
    
    class F4(Base):pass
    
    class F5(object):pass
    
    class F6(F5):pass
    
    import sys
    def func():
        name_lst = dir(sys.modules[__name__])
        obj_list = []
        for name in name_lst:
            name_addr = getattr(sys.modules[__name__],name)
            print(type(name_addr))
            if type(name_addr) is type and issubclass(name_addr,Base) and name_addr is not Base:
                obj_list.append(name_addr())
        return obj_list
    ret = func()
    print(ret)

    三,多继承

           1.不是所有的语言都支持多继承,例,jave,c#

            2.由于python支持多继承,所以python没有接口类

            3.其他不支持多继承的语言的接口类,相当于只是继承了一个规范,继承接口类规范的类必须实现接口类的方法

    #python的多继承语法
    class Parent1:pass
    class Parent2:pass
    class Son(Parent1,Parent2):pass
    print(Son.__bases__)   #__bases__查看所有父类,__base__只查看从左到右继承的第一个子类
    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()

      4.新式类和经典类

             #新式类:

             #所有的多继承关系寻找方法的顺序:遵循广度优先算法

             #继承object

             #mro方法

             #super:super()不是单纯的找父类,而是遵循mro顺序的    

              #经典类:

                 #python2.x

            #不主动继承object

            #经典类在找父类中方法的过程中,遵循:深度优先

          #不提供mro方法和super()

    # python 2.7
    # 经典类 和 新式类 并存
    # class Student:pass # 经典类
    # class Student(object):pass
    
    # 继承了object的类就是新式类
    # 在py3中所有的类都是新式类
    # 在py2中既有新式类又有经典类
    
    # 多继承的顺序 在新式类和经典类之间的区别
    class A:
        def func(self):
            print('A')
    
    class B(A):
        # pass
        def func(self):
            print('B')
    
    class C(A):
        # pass
        def func(self):
            print('C')
    
    class D(B,C):
        # pass
        def func(self):
            print('D')
    print(D.mro())
    d = D()
    d.func()

            

  • 相关阅读:
    <排序算法> 计数排序CountSort
    <排序算法> 直接插入排序InsertSort
    <排序算法> 快速排序QuickSort
    C# 获取文件的后缀,文件名和路径
    C# 移除HTML标签
    无限层级数
    iOS通用链接配置
    iOS 最新证书制作流程、制作通用证书
    C# FormData 文件太大报错404 Form表单上传大文件,无法进入后台Action,页面提示404.
    IS加载JSON 和 MP4文件 错误 404 提示 需要添加mime映射(默认IIS Express里没有映射)
  • 原文地址:https://www.cnblogs.com/lianyeah/p/9549094.html
Copyright © 2020-2023  润新知