美文网首页
Python OOP-3

Python OOP-3

作者: 若尘___ | 来源:发表于2021-03-02 10:10 被阅读0次

    6.3 多态

    • 多态就是同一个对象在不同情况下有不同的状态出现

    • 多态不是语法,是一种设计思想

    • 多态性:一种调用方式,不同的执行效果

    • 多态:同一事物的多种形态,动物分为人类、猪类、狗类

    • 多态和多态性

    • Mixin设计模式

    • 我们使用多继承语法来实现Mixin

    • 使用Mixin实现多继承的时候非常小心

      • 首先他必须表示某一单一功能,而不是某个物品
      • 职责必须单一,如果有多个功能,则写多个Mixin
      • Mixin不能依赖于子类的实现
      • 子类即使没有继承这个Mixin类,也能照样工作,只是缺少了某个功能
    • 优点

      • 使用Mixin可以在不对类进行任何修改的情况下,扩充功能
      • 可以方便的组织和维护不同功能组件的划分
      • 可以根据需要任意调整功能类的组合
      • 可以避免创建很多新的类,导致类的继承混乱

    7. 类相关函数

    • issubclass:检测一个类是否是另一个类的子类
    • isinstance:检测一个对象是否是一个类的实例
    • hasattr:检测一个对象是否有成员xxx
    • getattr:get attribute
    • setattr:set attribute
    • delattr:delete attribute
    • dir:获取对象的成员列表
    class A():
        pass
    
    class B(A):
        pass
    
    class C(B,A):
        pass
    
    print(A.__mro__)
    print(B.__mro__)
    
    (<class '__main__.A'>, <class 'object'>)
    (<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
    
    # 多继承的例子
    # 子类可以直接拥有父类的属性和方法,私有属性和方法除外
    class Fish():
        def __init__(self, name):
            self.name = name
            
        def swim(self):
            print("I am swimming......")
            
    class Bird():
        def __init__(self, name):
            self.name = name
            
        def fly(self):
            print("I am flying.....")
            
    class Person():
        def __init__(self, name):
            self.name = name
            
        def worked(self):
            print("Working......")
            
    class SuperMan(Person, Bird, Fish):
        def __init__(self, name):
            self.name = name    
            
    s = SuperMan("a")
    s.fly()
    s.swim()
    s.worked()
    
    
    # 单继承的例子
    
    class Student(Person):
        def __init__(self, name):
            self.name = name
            
    stu = Student("a")
    stu.worked()
    
    I am flying.....
    I am swimming......
    Working......
    Working......
    
    # 菱形继承问题
    class A():
        pass
    class B(A):
        pass
    class C(A):
        pass
    
    class D(B,C):
        pass
    
    # 构造函数例子
    
    class Person():
        # 对Person类进行实例化的时候
        # 姓名要确定
        # 年龄得确定
        # 地址肯定有
        def __init__(self):
            self.name = "NoName"
            self.age = 18
            self.address = "Studentwhonheim"
            print("In init func")
    
    # 实例化一个人
    p = Person() 
    
    In init func
    
    # 构造函数的调用顺序 - 1
    # 如果子类没有写构造函数,则自动向上查找,直到找到为止
    class A():
        def __init__(self):
            print("A")
    class B(A):
        def __init__(self):
            print("B")
    
    class C(B):
        pass
    
    # 此时,首先C的构造函数
    # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
    c = C()
    
    A
    
    # 构造函数的调用顺序 - 2
    class A():
        def __init__(self):
            print("A")
    class B(A):
        def __init__(self, name):
            print("B")
            print(name)
    
    class C(B):
        pass
    
    # 此时,首先C的构造函数
    # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
    # 此时,会出现参数结构不对应错误
    c = C()
    
    ---------------------------------------------------------------------------
    
    TypeError                                 Traceback (most recent call last)
    
    <ipython-input-11-40c74f7fff64> in <module>
         14 # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
         15 # 此时,会出现参数结构不对应错误
    ---> 16 c = C()
    
    
    TypeError: __init__() missing 1 required positional argument: 'name'
    
    # 构造函数的调用顺序 - 3
    class A():
        def __init__(self):
            print("A")
    class B(A):
        def __init__(self, name):
            print("B")
            print(name)
    
    class C(B):
        # C中想扩展B的构造函数
        # 即调用B的构造函数后再添加一些功能
        # 有两种方法实现
        
        '''
        # 第一种是通过父类名调用
        def __init__(self, name):
            # 首先调用父类构造函数
            B.__init__(self, name)
            # 其次,再增加自己的功能
            print("这是C中附加的功能")
        '''
        
        # 第二种,使用super调用
        def __init__(self, name):
            # 首先调用父类构造函数
            super(C, self).__init__(name)
            # 其次,再增加自己的功能
            print("这是C中附加的功能")
    
    # 此时,首先C的构造函数
    # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
    # 此时,会出现参数结构不对应错误
    c = C("我是C")
    
    B
    我是C
    这是C中附加的功能
    
    # Mixin案例
    
    class Person():
        name = "ruochen"
        age = 18
        
        def eat(self):
            print("EAT......")
            
        def drink(self):
            print("DRINK......")
        
        def sleep():
            print("SLEEP......")
    
    class Teacher(Person):
        def work(self):
            print("Work")
            
    class Student(Person):
        def study(self):
            print("Study")
            
    class Tutor(Teacher, Student):
        pass
    
    t = Tutor()
    
    print(Tutor.__mro__)
    print(t.__dict__)
    print(Tutor.__dict__)
    
    print("*" * 20)
    class TeacherMixin():
        def work(self):
            print("Work")
            
    class StudentMixin():
        def study(self):
            print("Study")
            
    class TutorM(Person, TeacherMixin, StudentMixin):
        pass
    
    tt = TutorM()
    print(TutorM.__mro__)
    print(tt.__dict__)
    print(TutorM.__dict__)
    
    (<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)
    {}
    {'__module__': '__main__', '__doc__': None}
    ********************
    (<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.StudentMixin'>, <class 'object'>)
    {}
    {'__module__': '__main__', '__doc__': None}
    
    # issubclass
    class A():
        pass
    
    class B(A):
        pass
    
    class C():
        pass
    
    print(issubclass(B, A))
    print(issubclass(C, A))
    print(issubclass(C, object))
    
    True
    False
    True
    
    # isinstance
    class A():
        pass
    
    a = A()
    
    print(isinstance(a, A))
    print(isinstance(A, A))
    
    True
    False
    
    # hasattr
    class A():
        name = "NoName"
    
    a = A()
    print(hasattr(a, "name"))
    print(hasattr(a, "age"))
    
    True
    False
    
    # help案例
    # 我想知道setattr的具体用法
    help(setattr)
    
    Help on built-in function setattr in module builtins:
    
    setattr(obj, name, value, /)
        Sets the named attribute on the given object to the specified value.
        
        setattr(x, 'y', v) is equivalent to ``x.y = v''
    
    # dir 案例
    class A():
        pass
    # dir(A)
    a = A
    dir(a)
    
    ['__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__']
    

    相关文章

      网友评论

          本文标题:Python OOP-3

          本文链接:https://www.haomeiwen.com/subject/krstqltx.html