Python面向对象之多态和鸭子类型
1259 字
6 分钟
Python面向对象之多态和鸭子类型
【一】多态
【1】什么是多态
- 多态指的是一类事物有多种形态
【2】示例
- 比如动物有多种形态:猫、狗、猪
import abc
# 同一类事物:动物class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def talk(self): pass
# 动物的形态之一:人class People(Animal): def talk(self): print('你真帅')
# 动物的形态之二:狗class Dog(Animal): def talk(self): print('汪汪汪')
# 动物的形态之三:猪class Pig(Animal): def talk(self): print('哼唧哼唧')- 文件有多种形态:文本文件,可执行文件
import abc
# 同一类事物:文件class File(metaclass=abc.ABCMeta): @abc.abstractmethod def click(self): pass
# 文件的形态之一:文本文件class Text(File): def click(self): print('open file')
# 文件的形态之二:可执行文件class ExeFile(File): def click(self): print('execute file')【二】多态性
【1】什么是多态动态绑定(多态性)
- 多态动态绑定在继承的背景下使用时,有时也称为多态性
- 多态性是指在不考虑实例类型的情况下使用实例
- 在面向对象方法中一般是这样表述多态性:
- 向不同的对象发送同一条消息(!!!obj.func()<是调用了obj的方法func>是调用了obj的方法func>,又称为向obj发送了一条消息func)
- 不同的对象在接收时会产生不同的行为(即方法)。
- 也就是说,每个对象可以用自己的方式去响应共同的消息。
- 所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
- 比如:老师.下课铃响了(),学生.下课铃响了()
- 老师执行的是下班操作
- 学生执行的是放学操作
- 虽然二者消息一样,但是执行的效果不同
【2】多态性的分类
- 多态性分为静态多态性和动态多态性
(1)静态多态性
- 如任何类型都可以用运算符 + 进行运算
(2)动态多态性
import abc
# 同一类事物:动物class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def talk(self): pass
# 动物的形态之一:人class People(Animal): def talk(self): print('你真帅')
# 动物的形态之二:狗class Dog(Animal): def talk(self): print('汪汪汪')
# 动物的形态之三:猪class Pig(Animal): def talk(self): print('哼唧哼唧')
peo = People()dog = Dog()pig = Pig()
# peo、dog、pig都是动物,只要是动物肯定有talk方法# 于是我们可以不用考虑它们三者的具体是什么类型,而直接使用peo.talk()dog.talk()pig.talk()
# 更进一步,我们可以定义一个统一的接口来使用def func(obj): obj.talk()- Python中一切皆对象,本身就支持多态性
# 我们可以在不考虑三者类型的情况下直接使用统计三个对象的长度s.__len__()l.__len__()t.__len__()
# Python内置了一个统一的接口len(s)len(l)len(t)【3】为什么要用多态性(多态性的好处)
- 增加了程序的灵活性
- 以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
- 增加了程序额可扩展性
- 通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
import abc
# 同一类事物:动物class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def talk(self): pass
# 属于动物的另外一种形态:猫class Cat(Animal): def talk(self): print('喵喵喵')
# 对于使用者来说,自己的代码根本无需改动def func(animal): animal.talk()
# 实例出一只猫cat1 = Cat()# 甚至连调用方式也无需改变,就能调用猫的talk功能func(cat1)- 这样我们新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。
- 使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1)
【三】鸭子类型 duck-typing
【1】什么是鸭子类型 duck-typing
- 鸭子类型是一种编程风格,决定一个对象是否有正确的接口
- 关注点在于它的方法或属性
- 而不是它的类型(如果它看起来像鸭子,像鸭子一样嘎嘎叫,那么它一定是鸭子。)。
- 通过强调接口而不是特定类型,设计良好的代码通过多态提高了灵活性。
- 鸭子类型无需使用 type() 或 isinstance() 进行检查(注意,鸭子类型可以用抽象基类来补充)
- 相反,它通常使用 hasattr() 来检查,或是 EAFP 编程。
- 但其实我们完全可以不依赖于继承,只需要制造出外观和行为相同对象,同样可以实现不考虑对象类型而使用对象,这正是Python崇尚的“鸭子类型”(duck typing):
- “如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”。
- 比起继承的方式,鸭子类型在某种程度上实现了程序的松耦合度
【2】鸭子类型
# 二者都像鸭子,因而就可以当鸭子一样去用class NormalDuck(): def eat(self): print(f"正常鸭子可以吃饭")
def walk(self): print(f"正常鸭子可以走路")
class RockDuck(): def eat(self): print(f"肉鸭子可以吃饭")
def walk(self): print(f"肉鸭子可以走路")支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章智能推荐
1
C 语言数据类型
编程语言理解 C 语言的数据类型体系,包括基本类型、整数类型、浮点类型和逻辑类型。
2
C 语言强制类型转换
编程语言学习 C 语言显式与隐式类型转换、整数提升及其常见使用场景。
3
C 语言变量与存储类型
编程语言理解 C 语言变量的定义、命名规则、作用域,以及 auto、register、extern 和 static 存储类型。
4
C 语言基础:注释、关键字、变量与数据类型
编程语言学习 C 语言的注释、关键字、标识符、常量、变量和基本数据类型等基础知识。
5
C 语言发展史
编程语言了解 C 语言从 BCPL、B 语言到现代标准 C 的发展历程、核心特点与应用领域。
随机文章随机推荐














