Object-oriented inheritance 02

  • Inheritance: Repeat the code to solve

    #继承语法 class 子类名(父类名):pass
    class A:
        pass
    class B(A):
        pass
    
    # A 父类 基类 超类
    # B子类 派生类
    • Subclass can use the parent class: methods and static variables

      class Animal:
          def __init__(self,name):
              self.name = name
          def eat(self):
              print('%s is eating'%self.name)
          def drink(self):
              print('%s is drinking'%self.name)
          def sleep(self):
              print('%s is sleeping'%self.name)
      class Cat(Animal):
          def climb_tree(self):
              print('%s is climbing'%self.name)
      
      class Dog(Animal):
          def house_keep(self):
              print('%s house keeping'%self.name)
      
      小白 = Cat('小白')
          # 先开辟空间,空间里有一个类指针-->指向Cat
          # 调用init,对象在自己的空间中找init没找到,到Cat类中找init也没找到,
          # 找父类Animal中的init
      小白.eat()#小白 is eating
      小白.climb_tree()#小白 is climbing
      小黑 = Dog('小黑')
      小黑.eat()#小黑 is eating
    • When the parent class and subclass of the same name, we use only for subclasses, and not to call the parent class method

      class Animal:
          def __init__(self,name):
              self.name = name
          def eat(self):
              print('%s is eating'%self.name)
          def drink(self):
              print('%s is drinking'%self.name)
          def sleep(self):
              print('%s is sleeping'%self.name)
      
      class Cat(Animal):
          def eat(self):
              print('%s吃猫粮'%self.name)
      
          def climb_tree(self):
              print('%s is climbing'%self.name)
      
      小白 = Cat('小白')
      小白.eat()#小白吃猫粮
    • At the same time you want to subclass method calls the parent class would like to implement their own methods of the same name

      • Call the parent class method in a subclass of the method: the name of the parent class method name (self)

        class Animal:
            def __init__(self,name,food):
                self.name = name
                self.food = food
                self.blood = 100
                self.waise = 100
            def eat(self):
                print('%s is eating %s'%(self.name,self.food))
            def drink(self):
                print('%s is drinking'%self.name)
            def sleep(self):
                print('%s is sleeping'%self.name)
        
        class Cat(Animal):
            def eat(self):
                self.blood += 100
                Animal.eat(self)
            def climb_tree(self):
                print('%s is climbing'%self.name)
                self.drink()
        
        class Dog(Animal):
            def eat(self):
                self.waise += 100
                Animal.eat(self)
            def house_keep(self):
                print('%s is keeping the house'%self.name)
        小白 = Cat('小白','猫粮')
        小黑 = Dog('小黑','狗粮')
        小白.eat()#小白 is eating 猫粮
        小黑.eat()#小黑 is eating 狗粮
        print(小白.__dict__)#{'name': '小白', 'food': '猫粮', 'blood': 200, 'waise': 100}
        print(小黑.__dict__)#{'name': '小黑', 'food': '狗粮', 'blood': 100, 'waise': 200}
        
        #父类和子类方法的选择:
        # 子类的对象,如果去调用方法
        # 永远优先调用自己的
            # 如果自己有 用自己的
            # 自己没有 用父类的
            # 如果自己有 还想用父类的 : 直接在子类方法中调父类的方法 父类名.方法名(self)
  • Single inheritance

    # 单继承
    # 调子类的 : 子类自己有的时候
    # 调父类的 : 子类自己没有的时候
    # 调子类和父类的 :子类父类都有,在子类中调用父类的
    class D:
        def func(self):
            print('in D')
    class C(D):pass
    class A(C):
        def func(self):
            print('in A')
    class B(A):pass
    B().func()
  • Multiple Inheritance

    • There are some languages ​​such as java does not support multiple inheritance
    • Features python language: You can support multiple inheritance in object-oriented
    # 多继承
    # 一个类有多个父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找
    class D:
        def func(self):
            print('in D')
    class C(D):pass
    class A(C):
        def func(self):
            print('in A')
    class B(A):pass
    B().func()
  • object class class fathers

    • All classes are inherited among python3 object class

      class A:pass
      print(A.__bases__)#(<class 'object'>,)
      class C:pass
      class B(A,C):pass
      print(B.__bases__)#(<class '__main__.A'>, <class '__main__.C'>)只能找到父类 不能找到父类的父类
  • Bound methods and common function
    from types import FunctionType,MethodType
    # FunctionType : 函数
    # MethodType : 方法
    class A:
        def func(self):
            print('in func')
    
    print(A.func)  # 函数 #<function A.func at 0x000002841C479488>
    a = A()
    print(a.func)  # 方法 #<bound method A.func of <__main__.A object at 0x000002841C308240>>
    print(isinstance(a.func,FunctionType))#False
    print(isinstance(a.func,MethodType))#True
    print(isinstance(A.func,FunctionType))#True
    print(isinstance(A.func,MethodType))#False
    
    #类.func是函数
    #对象.func是方法
  • pickel serializable objects

    • Premise py file, there are objects of class

      class Course:
          def __init__(self,name,period,price):
              self.name = name
              self.period = period
              self.price = price
      
      python = Course('python','6 moneth',21800)
      linux = Course('linux','5 moneth',19800)
      go = Course('go','4 moneth',12800)
      import  pickle
      with open('pickle_file','ab') as f:
          pickle.dump(linux,f)
          pickle.dump(go,f)
      with open('pickle_file','rb') as f:
          while True:
              try:
                  obj = pickle.load(f)
                  print(obj.name,obj.period)
              except EOFError:
                  break
      

      Advanced inheritance

Class inheritance

Multiple Inheritance

  • As long as the new class that inherits object class
  • Not inherit the object class are Classic

In python3 All classes inherit object class, they are the new class

Python2 not inherit the object in the class are classic classes, inheritance object class is a new class

Classic: does not exist in py3 is not active in py2 inherited object of class

在py2中
class A:pass   #经典类
class B(object):pass#新式类

在py3中
class A:  #pass #新式类
class B(object):pass #新式类

In single inheritance (whether it is a new class or Classic are the same)

class A:
    def func(self):pass
class B(A):
    def func(self):pass
class C(B):
    def func(self):pass
class D(c):
    def func(self):pass
d = D()

寻找某一个方法的顺序:D->C->B->A
越往父类走,是深度

Multiple Inheritance

class A:
    def func(self):
        print('A')
class B(A):
    def func(self):
        print('B')
class C(A):
    def func(Self):
        print(C)
class D(B,C):
    def func(self):
        print('B')
print(D.mro()) #只在新式类中有,经典类没有
d = D()
d.func()
在走到一个点,下一个点既可以深度走,也可以从广度走的时候,总是先走广度,再走深度,广度优先
在经典类总,都是深度优先,总是在一条路走不通之后再换一条路,走过的点不会再走了

C3 algorithm

Algorithms content:

  1. If you are single inheritance so always follow the subclass - to calculate> order of the parent class search order
  2. If multiple inheritance is their need to follow this class, a parent class inheritance order, the order of succession parent 2
  3. The merge rule: If a class appear in the order from left to right on the left side of most all, did not appear in a different location, then the first order of succession as proposed in a class or a left to right order of appearance in the leftmost side, did not appear in another order so as to present the first in the order of succession
  4. If the first category in the sequence from left to right the first appears after the first, and is not, it can not be extracted, the sequence continues rearwardly in order to find other parent class above conditions
  • super - mro order to find in accordance with (Method relation mro) for a parent of the current class
  1. In python3 does not need to pass parameters to help us find a way to automatically under the same name as a class mro order of the current class of

  2. The new class in python2 in, we need to take the initiative to pass parameters super ( Object subclass name and subclass ) . Function name () , so that it can help us to call to the next class mre order of this subclass of method

    In python2 classic class does not support the use of super come to the next class

    class A(object):
        def func(self):print('A')
    class B(A):
        def func(self):
            super().func()
            print('B')
    class C(A):
        def func(self):
            super().func()
            print('C')
    class D(B,C):
        def func(self):
            super().func()
            print('D')
    D().func()
    '''
    A
    C
    B
    D
    
    '''
  3. Wherein the super (). Func () can also be written Super (D, Self) .FUNC () .

  4. In single inheritance procedures, super is to find the parent class:

    class User:
        def __init__(self,name):
            self.name = name
    class VIPUser(User):
        def __init__(self,name,level,strat_date,end_date):
            # User.__init__(self,name)
            # super().__init__(name)              # 推荐的
            # super(VIPUser,self).__init__(name)
            self.level = level
            self.strat_date = strat_date
            self.end_date = end_date
    
     '''
     解析:中间的# 的三种方式功能都是找到并执行父类中的__init__的方法,推荐使用
     super().__init__(name)。
     '''
        先找每个类的继承关系(注意因为加载顺序的缘故从,上至下开始寻找)
    
        A(0) = [AO]      # A 继承于object类 
    
        B(A) = [BAO]      # B继承于A类
    
        C(A) = [CAO]     # C继承于A类
    
        D(B) = [DBAO]       # D继承于B类
    
        E(C) = [ECAO]       # E继承于C类
    
        那么算法为:
    
        F(D,E) = merge(D(B)+E(C))
    
        ​    = [F] + [DBAO] + [ECAO]
    
        F = [DBAO] + [ECAO]
    
        FD = [BAO] + [ECAO]
    
        FDB = [AO] + [ECAO]
    
        FDBE = [AO] + [CAO]
    
        FDBEC = [AO] + [AO]  
    
        FDBECAO
    
      - **使用子类名.mro() 查看继承顺序**
    
        只有新式类中有,经典类没有的。
    1. Development specifications through inheritance class
  5. Constraints parent subclasses

    1. The general category class ABC etc.

    2. Abstract class

      • Is a development of the specification, binding on all subclasses of his methods and his namesake must be implemented

      Introduction: Example: different form of payment

      class Wechat():
          def __init__(self,name):
              self.name = name
          def pay(self,money):
            print('%s通过微信支付%s钱成功'%(self.name,money))
      
      class Alipay():
          def __init__(self,name):
              self.name = name
          def pay(self,money):
              print('%s通过微信支付%s钱成功'%(self.name,money))
      
      class Apple(Payment):
          def __init__(self,name):
              self.name = name
          def pay(self,money):
              dic = {'name': self.name, 'number': money}
              # 想办法调用苹果支付 url连接 把dic传过去
              print('%s通过苹果支付%s钱成功' % (self.name, money))
      
      aw = WeChat('alex')
      aw.pay(400)
      aa = Alipay('alex')
      aa.pay(400)
      '''
      这样我们通过创建了2个对象,然后调用类中的方法pay,把钱传入完成支付的功能
      '''

      Of course, we sometimes need to normalize Design:

      def pay(name,price,kind):
          if kind == 'Wechat':
              obj = WeChat(name)
          elif kind == 'Alipay':
              obj = Alipay(name)
          elif kind == 'Apple':
              obj = Apple(name)
          obj.pay(price)
      pay('alex',400,'Wechat')
      pay('alex',400,'Alipay')
      pay('alex',400,'Apple')
      '''
      我们通过定义一个函数,通过判别传入的kind参数,选择创建实例化name对象,然后调用方法,完成付款。
      '''

      Note: to complete the above requirements need to pay three class method name is not the same as if the error is reported.

      Introduced to solve the above problems abstract class subclass related constraints

      class Payment:
        def pay(self,money):
              raise NotImplementedError('请在子类中重写同名pay方法')
      class Alipay(Payment):pass
      class WeChat(Payment):pass    
      class Apple(Payment): pass
      def pay(name,price,kind):
          if kind == 'Wechat':
              obj = WeChat(name)
          elif kind == 'Alipay':
              obj = Alipay(name)
          elif kind == 'Apple':
              obj = Apple(name)
          obj.pay(price)
      '''
      解析:我们创建一个所有类的父类,定义一个pay的方法,如果执行,则抛出异常。
      当我们执行pay函数时,我们会调用方法 pay ,当对象中没有pay的方法时,就会去父类Payment中调用,所以抛出异常。所以加入抽象类约束我们子类中方法名称一致。
      
      '''
      
      
      # 另一种方式:依赖于abc 模块
      from abc import ABCMeta,abstractmethod
      class Payment(metaclass=ABCMeta):
          @abstractmethod
          def pay(self,money):
              '''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法'''
              raise NotImplementedError('请在子类中重写同名pay方法')
      
      # 一旦子类中没有pay方法,实例化都无法完成。
      方式特点:约束力强。缺点:依赖于abc模块
      
  6. Polymorphism

    1. python everywhere is polymorphic, everything is an object

    2. What is polymorphic, with java explain

      A type of performance out of a variety of state

      In Java: a parameter must specify the type, so if you want both types of objects can pass, you must make maybe a class inherits from a parent class, specify the type of time and then use the parent class to specify

    3. Ducks type

      class list:
          def __len__(self):pass
      class dict:
          def __len__(self): pass
      class set:
          def __len__(self): pass
      class tuple:
          def __len__(self): pass
      class str:
          def __len__(self): pass
      def len(obj):
          return obj.__len__()
      # 如上述所有实现了__len__方法的类,在调用len函数的时候,obj都说是鸭子类型。
      # 再如:迭代器协议 __iter__ __next__ 是迭代器。即所有的迭代器都是鸭子类型

Guess you like

Origin www.cnblogs.com/lianzibing/p/10993648.html