多态
多态是指对象可以有多种形态,比如猫,狗,猪都属于动物有叫的行为,但是叫的方式不同,猫是喵喵叫、狗是汪汪叫。(一个抽象类有多个子类,因而多态的概念依赖于继承)。
多态不是语法是一种设计思想,可以这样理解,不同的对象都可以响应同一个方法,但执行结果各不相同。
多态性
多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数
实现
- 继承:不同子类 继承 同一父类
- 重写:子类重写 同一个方法,保证执行结果各不相同
实例
class Dog(object): # 定义父类def work(self):passclass ArmyDog(Dog): # 定义子类,并重写父类方法def work(self):print('追击敌人')class DrugDog(Dog):def work(self):print('追查毒品')class Person(object): # 定义人类,用于对象调用def work_with_dog(self, dog):dog.work()aa = ArmyDog()dd = DrugDog()kuma = Person()kuma.work_with_dog(aa) # 传递子类对象给调用者kuma.work_with_dog(dd)
多态代码详解:不同子类继承同一父类,重写要执行的方法,保证执行结果各不相同.多态可以看做 接口函数的重用,同一种接口方法 通过 接收不同的类 对象,从而实现不同的功能
鸭子类型
事实上 Python 不支持多态也不用多态,而是崇尚鸭子类型。鸭子类型:一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
实际生产环境中,主要用于 接口开发,即用同一个函数接收不同的类对象,从而实现不同的功能,而且无需关注对象之间的继承关系
实现
- 编写一个函数,用于接收要调用方法的对象
- 使用鸭子模型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的方法 ```python def animal_speak(obj): # 定义个函数用于接收具有 speak() 方法的对象 obj.speak()
class Duck(object): # 定义几个有 speak() 方法的类 def speak(self): print(‘鸭在叫’)
class Bird(object): # Bird 类与 Duck 类无继承关系 def speak(self): print(‘鸟在叫’)
class Dog(object): # Dog 类与 Duck 类无继承关系 def speak(self): print(‘狗在叫’)
duck = Duck()
dog = Dog() # dog 实例与 duck 实例无任何关系
bird = Bird()
animal_speak(dog) # duck、bird、dog 调用 animal_speak 方法,得到三种不同的结果,符合多态的特征 animal_speak(bird)
animal_speak(duck)
狗在叫 鸟在叫 鸭在叫 ``` 鸭子模型让代码比多态更加灵活度,鸭子模型不关关心类对象是什么,不需要类之间具有继承关系; 鸭子模型中,接收不同的类将会产生不同的行为,而无须明确知道这个类实际上是什么,这是多态的重要应用场景;
拓展
单例:在一个类整个程序运行期间最多只能有一个对象被创建。Python 单例创建有装饰器、元类等多种方式,但是推荐用 new 方式创建
class User(object):__instance = Nonedef __new__(cls, *args, **kwargs):if not cls.__instance:cls.__instance = super().__new__(cls)return cls.__instanceu1 = User('kuma')s1 = User('geon')print(id(u1))print(id(s1))----------------------------------------------------->>> 140671789338480>>> 140671789338480
根据 SF 社区意见 Python 不需要单例,因为 Python 有模块(module),最 pythonic 的单例典范
