Python面向对象——多态

news/2024/9/22 20:59:28/

目录

多态性的实现方式

1. 方法重写(Method Overriding)

2. 使用基类类型的引用

多态性的应用

示例:图形绘制

多态性与鸭子类型

关键点

总结


在面向对象编程中,多态性(Polymorphism)是指相同的操作可以作用于不同的对象,并且可以根据对象的类型表现出不同的行为。多态性使得程序具有更好的扩展性和灵活性。

在 Python 中,多态性的实现主要依赖于继承和方法重写。具体来说,多态性允许使用基类类型的引用来引用子类对象,并且在运行时调用子类的重写方法。

多态性的实现方式

1. 方法重写(Method Overriding)

在继承中,子类可以重写父类的方法。这是实现多态性的基础。

python">class Animal:def speak(self):raise NotImplementedError("Subclass must implement abstract method")class Dog(Animal):def speak(self):return "Woof!"class Cat(Animal):def speak(self):return "Meow!"# 创建对象
dog = Dog()
cat = Cat()# 调用方法
print(dog.speak())  # 输出: Woof!
print(cat.speak())  # 输出: Meow!

在这个例子中,DogCat 类都重写了 Animal 类的 speak 方法。当调用 speak 方法时,具体的实现由具体的对象决定。

2. 使用基类类型的引用

多态性使得可以用基类类型的引用来引用子类对象,并且在运行时调用子类的重写方法。

python">class Animal:def speak(self):raise NotImplementedError("Subclass must implement abstract method")class Dog(Animal):def speak(self):return "Woof!"class Cat(Animal):def speak(self):return "Meow!"def animal_speak(animal: Animal):print(animal.speak())# 创建对象
dog = Dog()
cat = Cat()# 使用基类类型的引用
animal_speak(dog)  # 输出: Woof!
animal_speak(cat)  # 输出: Meow!

在这个例子中,animal_speak 函数接受一个 Animal 类型的参数,但在运行时,可以传入任何 Animal 的子类对象,并且会调用相应子类的 speak 方法。

多态性的应用

多态性在实际应用中非常有用,特别是在需要处理一组具有不同具体实现的对象时。

示例:图形绘制

假设我们有一个图形绘制程序,支持绘制不同类型的图形(如圆形、矩形)。可以使用多态性来实现这个需求。

python">class Shape:def draw(self):raise NotImplementedError("Subclass must implement abstract method")class Circle(Shape):def draw(self):return "Drawing a Circle"class Rectangle(Shape):def draw(self):return "Drawing a Rectangle"# 定义一个绘图函数
def draw_shape(shape: Shape):print(shape.draw())# 创建对象
circle = Circle()
rectangle = Rectangle()# 使用多态性
draw_shape(circle)      # 输出: Drawing a Circle
draw_shape(rectangle)   # 输出: Drawing a Rectangle

在这个例子中,不同的图形类(如 CircleRectangle)都实现了 Shape 类的 draw 方法。使用多态性,可以通过 Shape 类型的引用来调用具体图形对象的 draw 方法。

多态性与鸭子类型

Python 是一种动态类型语言,除了通过继承实现多态性外,还可以通过鸭子类型(Duck Typing)实现多态性。鸭子类型是一种动态类型系统,在这种系统中,一个对象是否能使用取决于它是否具有所需的方法或属性,而不是它的实际类型。

在 Python 中,鸭子类型(Duck Typing)的概念来自一句谚语:“如果它走路像鸭子,叫声像鸭子,那么它就是一只鸭子。”也就是说,一个对象的类型和方法是否可以用并不取决于这个对象的实际类型,而是它是否具有某个方法或属性。

在传统的静态类型语言中,一个函数的参数类型通常是固定的,这种类型检查是在编译时进行的。而在 Python 这样的动态类型语言中,类型检查是在运行时进行的。因此,只要传入的对象具有所需的方法或属性,Python 就会认为它是合适的类型。

python">class Bird:def fly(self):return "Bird is flying"class Airplane:def fly(self):return "Airplane is flying"def let_it_fly(obj):print(obj.fly())# 创建对象
bird = Bird()
airplane = Airplane()# 使用鸭子类型实现多态性
let_it_fly(bird)       # 输出: Bird is flying
let_it_fly(airplane)   # 输出: Airplane is flying

在这个例子中,let_it_fly 函数不关心传入对象的类型,只要对象具有 fly 方法即可。

关键点
  1. 动态类型检查

    • let_it_fly 函数不会在调用时检查 obj 的实际类型。
    • 只要 obj 具有 fly 方法,Python 就会调用它,而不关心 obj 是哪种类型的实例。
  2. 适配不同对象

    • 在例子中,Bird 类和 Airplane 类都有 fly 方法。
    • 当我们传递 birdBird 类的实例)或 airplaneAirplane 类的实例)给 let_it_fly 函数时,Python 会调用各自的 fly 方法,输出不同的结果。
  3. 灵活性

    • 这种方式使得函数可以适配更多类型的对象,只要这些对象具有所需的方法或属性,而不必严格继承自某个特定的类。

总结

  • 多态 使得相同的操作可以作用于不同的对象,并根据对象的类型表现出不同的行为。
  • 方法重写 是实现多态性的基础,子类可以重写父类的方法。
  • 可以使用基类类型的引用来引用子类对象,并在运行时调用子类的重写方法。
  • 在 Python 中,除了通过继承实现多态性外,还可以通过鸭子类型实现多态性。


http://www.ppmy.cn/news/1503347.html

相关文章

git学习笔记(总结了常见命令与学习中遇到的问题和解决方法)

前言 最近学习完git,学习过程中也遇到了很多问题,这里给大家写一篇总结性的博客,主要大概讲述git命令和部分难点问题(简单的知识点这里就不再重复讲解了) 一.git概述 1.1什么是git Git是一个分布式的版本控制软件。…

替换后端国外身份目录服务,宁盾身份域管接管FileNet助力国产化升级

IBM FileNet 是一款优秀的企业内容管理解决方案,为客户提供了领先的文档管理和流程管理集成环境,被大量企业所采用。FileNet 需要使用企业级的目录服务器(LDAP)作为其用户管理系统,满足其认证和授权的需求。对于 LDAP …

golang websocket 手写研究机制

// 处理ws请求 func WsHandler(w http.ResponseWriter, r *http.Request, id string) {var conn *websocket.Connvar err errorpingTicker : time.NewTicker(time.Second * 10)conn, err wsupgrader.Upgrade(w, r, nil)if err ! nil {log.Printf("Failed to set websocke…

Java类加载器实现机制详细笔记

1. 类加载器的基本概念 类加载器(ClassLoader):在Java中,类加载器负责将Java类动态加载到JVM中。它是实现动态类加载机制的核心组件,对于开发复杂应用程序(如插件系统、模块化设计等)至关重要。…

vue3前端开发-小兔鲜项目-登录和非登录状态下的模板适配

vue3前端开发-小兔鲜项目-登录和非登录状态下的模板适配&#xff01;有了上次的内容铺垫&#xff0c;我们可以根据用户的token来判定&#xff0c;到底是显示什么内容了。 1&#xff1a;我们在对应的导航组件内修改完善一下内容即可。 <script setup> import { useUserSt…

2024.7.19 作业

1.链表的排序 int list_sort(NodePtr L) {if(NULLL || L->len<1){printf("排序失败");return -1;}int lenL->len1;NodePtr p;int i,j;for( i1;i<len;i){for( j0,pL;j<len-i;j,pp->next){if( p->data > p->next->data ){datatype tp-&…

在Ubuntu子系统上安装宝塔面板(BT Panel)

在Ubuntu子系统上安装宝塔面板&#xff08;BT Panel&#xff09;&#xff0c;可以按照以下步骤进行&#xff1a; 更新系统软件包&#xff1a; 打开Ubuntu终端&#xff0c;输入以下命令更新系统软件包&#xff1a; sudo apt update && sudo apt upgrade -y安装必备的软件…

计算机网络 - 理解HTTP与HTTPS协议的关键区别与安全性

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有疑问和建议&#xff0c;请私信或评论留言&#xff01; 前言 在今天的互联网…