PythonOOP-3

    xiaoxiao2022-07-03  175

    6.3 多态

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

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

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

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

    多态和多态性

    Mixin设计模式

    主要采用多继承方式对类的功能进行扩展Mixin概念MRO and MixinMixin模式Mixin MROMRO

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

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

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

    优点

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

    7. 类相关函数

    issubclass:检测一个类是否是另一个类的子类isinstance:检测一个对象是否是一个类的实例hasattr:检测一个对象是否有成员xxxgetattr:get attributesetattr:set attributedelattr:delete attributedir:获取对象的成员列表 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__']
    最新回复(0)