Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

多态

原创
作者头像
Heaven645
发布于 2024-08-07 11:24:14
发布于 2024-08-07 11:24:14
12600
代码可运行
举报
文章被收录于专栏:Python学习Python学习
运行总次数:0
代码可运行

前言

多态(Polymorphism)是面向对象编程中的核心概念,本章将详细讲解 Python 中多态的实现方式以及如何应用多态提高代码的可维护性。


本篇文章参考:黑马程序员

一、基本概念

定义:

多态是指同一个行为通过不同的对象获得不同的结果或状态。

类型:

①鸭子类型(Duck Typing)

在 Python 中,我们不关注对象的具体类型,只关注对象是否具有某个方法或属性。如果一个对象能“像鸭子一样叫,像鸭子一样走”,那么即使它不是一个鸭子,Python 也能通过该对象执行操作。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
class Bird:  
    def fly(self):  
        return "I can fly!"  

class Airplane:  
    def fly(self):  
        return "I am an airplane!"  

class Fish:  
    def swim(self):  
        return "I can swim!"  

def lets_fly(thing):  
    print(thing.fly())  

# 使用鸭子类型  
bird = Bird()  
airplane = Airplane()  

lets_fly(bird)      # 输出: I can fly!  
lets_fly(airplane)  # 输出: I am an airplane!  
# lets_fly(Fish())  # 会出错,因为 Fish 类没有 fly 方法

输出结果:

I can fly!

I am an airplane!

【分析】

lets_fly() 函数期望传入一个具有 fly() 方法的对象。Bird 和 Airplane 类都实现了 fly() 方法,因此它们可以作为参数传递给 lets_fly()。由于Fish 没有 fly() 方法,如果 Fish 被传入,程序运行后会报错。

②方法重写(Method Overriding)

子类可重写父类的方法,以实现不同的功能。当通过父类调用这个方法时,会调用子类的实现。

思考:那我们前两章讲到的继承的复写和多态的方法重写有什么区别呢?

答:在 Python 中,继承中的复写(通常指方法重写)和多态中的方法重写实际上是同一个概念,都是指在子类中重写父类的方法,但其上下文和侧重点有所不同。

在继承关系中,子类重写父类的方法,目的是给该方法提供不同的实现,以满足子类的特定需求。这是一种语言级别的概念,侧重于代码的结构和重用。

而多态中的"方法重写"更广泛地应用于设计模式,它关注的是运行时的行为选择,强调的是基于接口而不是固定实现,允许根据实际使用的对象类型动态地调用相应的方法。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("汪汪汪")

class Cat(Animal):
    def speak(self):
        print("喵喵喵")

def make_noise(animal: Animal):
    # 制造噪音,需要传入Animal对象
    animal.speak()

# 使用两个子类对象调用函数
dog = Dog()
cat = Cat()

make_noise(dog)
make_noise(cat)

输出结果:

汪汪汪

喵喵喵

【分析】

父类 Animal 定义了一个方法 speak(),而子类 Dog 和 Cat 重写了该方法,提供各自特定的实现。函数 make_noise() 接受一个 Animal 类型的参数,它可以接受任何 Animal 的子类实例(如 Dog 或 Cat)。这是因为子类是父类的特例,Dog 和 Cat 类是对 Animal 的扩展,因此任何 Dog 或 Cat 的实例都可以被视为 Animal 的实例。

多态常用于继承关系中,允许以父类进行定义和声明,而以子类实现具体功能,从而实现相同的行为但具有不同的状态。

例如,当一个函数的参数声明为父类对象时,实际上可以传入其子类的对象来执行相应的操作,这使得我们能够通过统一的接口来处理不同类型的对象,从而实现灵活的代码设计。

异同点:

特征

鸭子类型

方法重写

定义

一种类型的特性通过行为来判断,而不是类型本身

在子类中重写父类的方法以提供不同的实现

实现方式

只需实现所需的方法

明确使用继承结构,子类根据需要重写父类方法

灵活性

高(适用于任何对象只要实现了必要的方法)

略低(依赖于类的继承关系)

关注点

强调对象行为而非类型

强调屏蔽父类的具体实现,提供自定义实现

使用场景

适合处理不同类型的对象,只要它们实现了同样的方法

适合在继承关系中有明确父子类关系的场景

二、抽象类

抽象类:包含抽象方法的类。

抽象方法:没有具体实现的方法

这种设计的意义在于父类定义了应包含的方法,而具体的实现则由子类负责决定。

例如,空调可以制冷、制热和左右扫风。我们将这三个功能制定为空调制造的标准,不同的厂家必须根据这个标准各自实现功能。抽象类可以看作是这种标准,它包含了一些抽象方法,要求子类必须实现这些方法。

这种设计的作用主要体现在以下几个方面:

  • 顶层设计:抽象类提供了一个设计标准,以便子类进行具体实。
  • 软性约束:抽象类对子类施加了一种约束,要求子类必须重写(实现)父类的一些方法。
  • 配合多态:通过多态的机制,我们可以获得不同的工作状态。
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 抽象类
class AC:
    # 制冷
    def cool_wind(self):
        pass

    # 制热
    def hot_wind(self):
        pass

    # 左右摆风
    def swing_l_r(self):
        pass


class Midea_AC(AC):
    def cool_wind(self):
        print("美的空调制冷")

    def hot_wind(self):
        print("美的空调制热")

    def swing_l_r(self):
        print("美的空调左右摆风")

class GREE_AC(AC):
    def cool_wind(self):
        print("格力空调制冷")

    def hot_wind(self):
        print("格力空调制热")

    def swing_l_r(self):
        print("格力空调左右摆风")

def make_cool(ac: AC):
    ac.cool_wind()

midea_ac = Midea_AC()
gree_ac = GREE_AC()

make_cool(midea_ac)
make_cool(gree_ac)

输出结果:

美的空调制冷

格力空调制冷

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面向对象详解,面向对象的三大特征:封装、继承、多态
面向对象编程(Object-Oriented Programming,简称OOP)和面向过程编程(Procedural Programming,简称PP)是两种不同的编程范式。
爱喝兽奶的熊孩子
2024/04/10
5.2K1
面向对象详解,面向对象的三大特征:封装、继承、多态
Python多态
多态:同类对象的多种形态,一个接口多种实现,(以封装和继承为前提),不同的子类调用相同的方法,产生不同的结果
王大力测试进阶之路
2019/10/25
7780
Python多态
【Python】面向对象 - 多态 ( 多态概念 | 多态用法 | 抽象类概念 | 代码示例 )
" 多态 " 指的是 多种状态 , 相同类型 的 不同 对象 完成 某个行为时 , 会得到不同的状态 ;
韩曙亮
2023/10/11
2880
【Python】面向对象 - 多态 ( 多态概念 | 多态用法 | 抽象类概念 | 代码示例 )
Python3 与 C# 面向对象之~继承与多态
文章汇总:https://www.cnblogs.com/dotnetcrazy/p/9160514.html
逸鹏
2018/06/23
1.7K2
Python3 与 C# 面向对象之~继承与多态
c++之多态
首先有父子关系,然后给父类中的某个函数加上viirtual关键字,子类对该函数进行重写,最后就可以实现动态多态。
西西嘛呦
2020/08/26
3380
盘点Python中的继承和多态
继承是一种创建新的类的方式,新创建的叫子类,继承的叫父类、超类、基类。继承的特点就是子类可以使用父类的属性(特征、技能)。继承是类与类之间的关系。
Python进阶者
2021/08/20
7390
深入解析C++中的虚函数和虚继承:实现多态性与继承关系的高级特性
虚函数是在C++中用于实现多态性的一种特殊函数。它通过使用关键字"virtual"进行声明,在基类中定义,可在派生类中进行重写。虚函数允许在运行时根据对象的实际类型来调用相应的函数,而不仅仅根据指针或引用的类型。这使得在继承关系中,通过基类指针或引用调用虚函数时,可以根据实际对象的类型来动态地确定要执行的函数版本,实现多态性的特性。
洁洁
2023/12/12
2.2K0
深入解析C++中的虚函数和虚继承:实现多态性与继承关系的高级特性
JAVA基础 | java基础4(JAVA继承、JAVA多态、抽象类、接口)
super 表示使用它的类的父类。super 可用于: 1.引用父类对象的成员变量 super.age;
网络技术联盟站
2019/10/13
1.2K1
面向对象编程(OOP):什么是面向对象编程?三大特性继承、多态、封装如何实现?
面向对象编程(Object-Oriented Programming, OOP)是一种将数据和操作数据的方法封装成对象的编程方式。它的核心思想是:
猫头虎
2024/12/18
4880
【Python基础编程】多态、静态方法与类对象的核心概念
上篇文章主要介绍了python面向对象继承、重写和super等,接下来继续了解多态,静态方法以及类相关的知识点。
易辰君
2024/11/07
1180
Java-多态
版权声明: https://blog.csdn.net/li_xunhuan/article/details/88932792
Fisherman渔夫
2019/07/31
5130
Java-多态
python 多态、组合、反射
上述例子,只要是动物就可以直接使用相同的方法!多态的存在其实也限制了子类的使用方法(抽象类也是可以限制子类),定义子类的时候,必须有speak()方法,这样才能算的上动物类,所以python推荐使用“鸭子类型”,是一种不依赖于继承,也可以实现不考虑对象类型而使用对象。
HammerZe
2022/03/25
6410
python 多态、组合、反射
Dart 中的封装 继承 多态
封装是面向对象编程中的一个基本概念,它的主要目的是将对象的状态(数据)和行为(方法)组合在一起,并隐藏对象的内部实现细节,只暴露必要的接口给外部使用。
心安事随
2024/11/28
1050
Java的多态
推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏网站,请点击下方链接查看。 https://www.captainbed.cn/f1
鲜于言悠
2024/05/31
1300
Java的多态
组合、封装、多态
继承:一种类与类的关系,一种什么是什么的关系,子类是父类的从属关系。 组合:对象与对象的关系,一种什么有什么的关系,一个对象拥有另一个对象。 组合优点:让类与类之间解耦,可扩展性高 组合的缺点:编写复杂度高 继承优点:编写复杂度低 继承缺点:耦合度高
GH
2019/12/12
5800
【Java面向对象三大特征——多态】
多态:完成某个行为,当不同对象去完成时会产生出不同的状态。(同一件事,发生在不同对象身上,产生不同的效果。eg:动物吃粮食这个动作,对于猫是吃猫粮,狗是吃狗粮。)
ImAileen
2024/12/04
1520
【Java面向对象三大特征——多态】
Python全栈开发之面向对象
类是对一群具有相同特征或者行为的事物统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就是一个模板
py3study
2020/01/10
4960
面向对象语言的三大特征: 封装 继承 多态(二)——继承
子类去重写父类中的方法, 当子类重写了父类中的方法,子类再调用该方法时 调用的是子类重写之后的
诡途
2020/10/16
4110
面向对象语言的三大特征: 封装 继承 多态(二)——继承
小朋友学Java(9):抽象类与接口
之前提过面向对象有三大特性:封装、继承、多态。 还有另一种说法,即面象对象有四大特性:抽象、封装、继承、多态。 这两种说法都是对的,不必拘泥于哪种说法。关键要能理解这些特性的含义。 在Java中,可以通过两种形式来体现面向对象的抽象:抽象类和接口。 一、抽象类 (一)抽象方法 在了解抽象类之前,先来了解一下抽象方法。抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。抽象方法的声明格式为: abstract void fun(); 抽象方法必须用abstract关键字进行修饰。 为什么需要抽象方法呢?因
海天一树
2018/04/17
6040
小朋友学Java(9):抽象类与接口
Python面向对象编程-多态的概念和使用
在面向对象编程中,多态是一个非常重要的概念。多态可以让不同的对象以相同的方式进行操作,从而增强了代码的灵活性和可重用性。
玖叁叁
2023/04/19
3300
推荐阅读
相关推荐
面向对象详解,面向对象的三大特征:封装、继承、多态
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验