python基础-面向对象编程之多态
面向对象编程之多态以及继承、抽象类和鸭子类型三种表现形式
多态
定义:同一种类型的事物,不同的形态
作用: 多态也称之为“多态性”。用于在不知道对象具体类型的情况下,统一对象调用方法的规范(比如说名字)
表现形式:有3种,分别是继承、抽象类和鸭子类型
-
继承:耦合度高,程序的可扩展性低
实现
- 父类:定义一套统一的规范(比如:方法名统一)
- 子类:遵循父类的统一规范(比如:子类遵循父类方法名称的统一)
-
抽象类:耦合度极高,程序的可扩展性极低
由于在python中,继承并不会强制子类必须要遵循父类的规范,因此出现了抽象类
定义:在python内置的abc模块中,有一个抽象类ABCMeta
作用:限制子类必须遵循父类的编写模块
实现
- 父类需要继承ABC模块中的ABCMeta,语法是
metaclass = ABCMeta
- 在父类的方法中,需要使用装饰器
abc.abstractmethod
注意:
1.
abc.abstractclassmethod
已经被停用了,在后期代码编写时,不要使用。abc.abstractmethod
是目前在用的装饰器2.在抽象类的表现形式下,父类中被abc.abstractmethod装饰的方法,子类必须按照父类的方法编写规范,缺一不可
3.在python中不推荐使用抽象类
""" 抽象类的实现 1. 导入模块 abc 2. 父类继承abc.ABCMeta类,语法:metaclass = abc.ABCMeta 3. 给父类的方法,装饰上 abc.abstractmethod 注意:abc.abstractclassmethod 已被停用,带删除线; 现使用abc.abstractmethod """ import abc # 父类Animal 继承abc.ABCMeta 类 class Animal(metaclass=abc.ABCMeta): # @abc.abstractclassmethod 已停用 # 装饰上abc.abstractmethod @abc.abstractmethod def speak(self): # 该方法被abstractmethod装饰,子类必须一致 print("from Animal") pass def run(self): # 该方法没有被装饰,子类可不保持一致 pass class Dog(Animal): def speak(self): print("汪汪汪……") def pao(self): print("旺财狂奔起来!!!!") dog = Dog() dog.speak() # 输出结果:汪汪汪…… dog.pao() # 输出结果:旺财狂奔起来!!!!
如果不按照父类的方法命名规范,则会报错
# 父类Animal参照👆上面的代码 # 子类Cat 继承父类Animal,但是没有speak方法,会怎样? class Cat(Animal): def jump(self): print("小黑跳跃起来……") cat = Cat() cat.jump() # 报错:TypeError: Can't instantiate abstract class Cat with abstract methods speak
- 父类需要继承ABC模块中的ABCMeta,语法是
-
鸭子类型:耦合度低,程序的可扩展性高(在python中,推荐使用此种方式)
定义:不同的对象,存在相同的方法,那么这些对象都属于鸭子类型
作用:不同对象,先抽象出相同类型的方法,给这些方法定制一套统一的规范。所有的类,在定义时都要按照统一的规范进行编写。
""" 给所有类的制定speak() 和 run() 这些类之间没有任何关系,只是遵循规则,都有speak和run方法 """ # 猫类 class Cat: def speak(self): print("from Cat:喵喵喵……") def run(self): print("from Cat:罗小黑加速!!!!") # 狗类 class Dog: def speak(self): print("from Dog:汪汪汪……") def run(self): print("from Dog:旺财冲啊!!!!") # 不论是哪个对象,都有speak()和run() # 创建cat对象 cat = Cat() # 调用speak() cat.speak() # 调用run() cat.run() # 创建dog对象 dog = Dog() # 调用speak() dog.speak() # 调用run() dog.run()