63 类的多态与多态性

510次阅读
没有评论

共计 2274 个字符,预计需要花费 6 分钟才能阅读完成。

一. 多态

1."甚么似" 多态

63 类的多态与多态性

多态是指一类事物有多种形态

2. 例 : 动物的多种形态 : 人, 鸭子, 猪...

class Animal:
    def speak(self):
        print(f" 开口说话 ")

#动物的形态之一: 人
class People(Animal):
    def speak(self):
        print('呵呵呵')

#动物的形态之二: 狗
class Duck(Animal):
    def speak(self):
        print('嘎嘎嘎')

#动物的形态之三: 猪
class Pig(Animal):
    def speak(self):
        print('咕咕咕')

Peo1 = People()
Duc1 = Duck()
Pig1 = Pig()

Peo1.speak()  # 呵呵呵
Duc1.speak()  # 嘎嘎嘎
Pig1.speak()  # 咕咕咕

Peo1, Duc1, Pig1 对象都属于一个类

同一类的事物调用相同的方法, 但执行的效果却不一样, 这就是多态

3. 例 : 文件的多种形态 : 文本文件, 可执行文件

class File:
    def click(self):
        pass

# 文件的形态之一: 文本文件
class Text(File):
    def click(self):
        print('打开文件')

# 文件的形态之二: 可执行文件
class ExeFile(File):
    def click(self):
        print('执行文件')

T1 = Text()
E1 = ExeFile()

T1.click()  # 打开文件
E1.click()  # 执行文件

T1, E1 属于同一个类, 但是他们调用同一个方法, 表现出来的效果却不一样


二. 多态性

1. 什么是多态性

多态性指的是在不考虑对象的具体类型下, 直接使用对象的方法, 同一种调用方式, 运行的效果不一样 (这就需要在设计时, 把对象的调用方法设计成形式统一的一种)

面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数

  • 例 : 下课铃响了(同一种调用方式), 老师执行下班的操作, 学生执行放学的操作(执行后的不同效果)
  • 例 : 每月十五号(同一种调用方式), 老板执行发工资操作, 员工执行收工资操作(执行后的不同效果)
  • 例 : 白晚班交替(同一种调用方式), 白班执行下班的操作, 晚班执行上班的操作(执行后的不同效果)

2. 多态性的使用

class Animal:
    def speak(self):
        print(f" 开口说话 ")

# 动物的形态之一: 人
class People(Animal):
    def speak(self):
        print('呵呵呵')

# 动物的形态之二: 狗
class Duck(Animal):
    def speak(self):
        print('嘎嘎嘎')

# 动物的形态之三: 猪
class Pig(Animal):
    def speak(self):
        print('咕咕咕')

Peo1 = People()
Duc1 = Duck()
Pig1 = Pig()

=============================================

🍔我们不去考虑 "Peo1, Duc1, Pig1" 这三个对象是什么类型, 他们都有 "speak" 方法

#定义一个统一的接口来使用
def Animal_speak(obj):
    obj.speak()

Animal_speak(Peo1)  # 呵呵呵
Animal_speak(Duc1)  # 嘎嘎嘎
Animal_speak(Pig1)  # 咕咕咕

3. 多态性的好处

  • 增加了程序的灵活性 : 对于使用者来说都是使用同一种方式去调用每个对象的方法
  • 增加了程序的可扩展性 : 如果我们新建一个类或者又实例出一个对象, 使用者无需更改自己的代码, 还是原来的调用方式
  • 新增实例 :
🍔新增一个 " 狗 " 类
class Dog(Animal):
    def speak(self):
        print(" 汪汪汪 ")

Dog1 = Dog()

🍔对于使用者来说代码不需要改变
def Animal_speak(obj):
    obj.speak()

🍔还是使用相同的调用方式
Animal_speak(Dog1)  # 汪汪汪

# 这样我们就新增了一个 "Dog" 形态, 产生了一个 "Dog1" 实例, 使用者可以在完全不需要修改自己代码的情况下, 使用之前一样的调用方式来调用 "Dog1" 的 "speak" 方法

三.abs 模块限制子类必须重写父类的某些方法

多态的前提是 : 同一类事物, 最好的方法就是让他们继承同一个基类

为了保证多态, 我们可以使用 abc 模块 来强制的要求子类必须重写父类的某些功能, 如果不重写, 则会报错

import abc

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod     # @abc.abstractmethod 装饰器后严格控制子类必须实现这个方法, 才能正常的实例化
    def speak(self):
        print(f" 开口说话 ")

class People(Animal):       # 子类继承了 "Animal" 类就必须重写指定的 "speak"
    def speak(self):
        print('呵呵呵')

class Duck(Animal):
    pass
    # def speak(self):      # "Duck" 没有重写
    #     print('嘎嘎嘎')

Peo1 = People()
Duc1 = Duck()               # 实例对象时就报错 "TypeError"

abs 模块使用小结

  • abs 模块 不是我们来保证多态的惯用做法, Python 中有其他方法可以实现
  • Python 中不推荐强制使用父类来约束子类, Python 推崇使用 鸭子类型 来实现多态
正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计2274字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)