Python 继承、多态、封装、抽象

news2024/11/5 4:39:06

面向对象编程(OOP)是 Python 中的一种重要编程范式,它通过类和对象来组织代码。OOP 的四个核心概念是继承(Inheritance)、多态(Polymorphism)、封装(Encapsulation)和数据抽象(Data Abstraction)。下面将详细介绍这四个概念。

继承(Inheritance)

继承是面向对象编程(OOP)的一个基本概念,它允许一个类(子类或派生类)继承另一个类(基类或父类)的属性和方法。继承促进了代码的重用,并有助于在类之间建立层次结构。在 Python 中,可以通过继承现有的基类来创建新的派生类。

继承的类型

1. 单继承(Single Inheritance)
  • 派生类从单个基类继承。

示例

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

dog = Dog("Buddy")
print(dog.speak())  # 输出: Buddy says Woof!
2. 多继承(Multiple Inheritance)
  • 派生类从多个基类继承。

示例

class Animal:
    def __init__(self, name):
        self.name = name

class Canine:
    def bark(self):
        return "Woof!"

class Dog(Animal, Canine):
    def speak(self):
        return f"{self.name} says {self.bark()}"

dog = Dog("Buddy")
print(dog.speak())  # 输出: Buddy says Woof!
3. 多级继承(Multilevel Inheritance)
  • 派生类从另一个派生类继承。

示例

class Animal:
    def __init__(self, name):
        self.name = name

class Mammal(Animal):
    def __init__(self, name, has_fur):
        super().__init__(name)
        self.has_fur = has_fur

class Dog(Mammal):
    def speak(self):
        return f"{self.name} says Woof!"

dog = Dog("Buddy", True)
print(dog.speak())  # 输出: Buddy says Woof!
4. 层次继承(Hierarchical Inheritance)
  • 多个派生类从单个基类继承。

示例

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())  # 输出: Buddy says Woof!
print(cat.speak())  # 输出: Whiskers says Meow!
5. 混合继承(Hybrid Inheritance)
  • 两种或多种继承类型的组合。通常涉及层次继承、多级继承和多继承的混合。

示例

class Animal:
    def __init__(self, name):
        self.name = name

class Canine(Animal):
    def bark(self):
        return "Woof!"

class Feline(Animal):
    def meow(self):
        return "Meow!"

class Dog(Canine):
    def speak(self):
        return f"{self.name} says {self.bark()}"

class Cat(Feline):
    def speak(self):
        return f"{self.name} says {self.meow()}"

dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())  # 输出: Buddy says Woof!
print(cat.speak())  # 输出: Whiskers says Meow!

详细解释

  1. 单继承

    • 最简单的继承形式,派生类从单个基类继承。
    • 适用于简单的类层次结构。
  2. 多继承

    • 派生类可以从多个基类继承。
    • 适用于需要从多个来源继承功能的场景。
    • 使用 super() 方法可以避免多重继承中的方法冲突。
  3. 多级继承

    • 派生类从另一个派生类继承,形成多级层次结构。
    • 适用于需要逐步细化功能的场景。
  4. 层次继承

    • 多个派生类从单个基类继承。
    • 适用于需要多个子类共享同一基类功能的场景。
  5. 混合继承

    • 两种或多种继承类型的组合。
    • 适用于复杂的类层次结构,需要灵活地组合多种继承方式。

注意事项

  • 方法解析顺序(MRO)

    • 在多继承中,Python 使用 C3 线性化算法来确定方法解析顺序(MRO)。
    • 可以使用 mro() 方法查看类的 MRO。
    • 例如:
      print(Dog.mro())
      
  • 使用 super()

    • super() 函数用于调用父类的方法,特别是在多继承中避免方法冲突。
    • 例如:
      class Mammal(Animal):
          def __init__(self, name, has_fur):
              super().__init__(name)
              self.has_fur = has_fur
      

多态(Polymorphism)

多态是面向对象编程(OOP)的一个核心概念,它允许不同类的对象被视为单一超类的成员。多态通过单一接口表示多种底层形式(数据类型),使得不同类可以提供同名但根据对象类具有不同行为的方法。多态通过方法重载和方法重写实现,促进了代码的灵活性和集成,使得编写通用、可重用的代码变得更加容易。

多态的基本概念

  1. 方法重写(Method Overriding)

    • 子类可以重写父类的方法,以提供不同的实现。
    • 通过方法重写,可以在子类中扩展或修改父类的行为。
  2. 方法重载(Method Overloading)

    • 同一个类中可以定义多个同名但参数不同的方法。
    • Python 本身不直接支持方法重载,但可以通过默认参数和可变参数等技术实现类似的效果。

示例

以下是一个展示多态的 Python 示例:

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

def make_animal_speak(animal):
    print(animal.speak())

dog = Dog()
cat = Cat()

make_animal_speak(dog)  # 输出: Woof!
make_animal_speak(cat)  # 输出: Meow!

封装(Encapsulation)

封装是面向对象编程(OOP)的一个核心概念,它将方法(函数)和数据(属性)组织成一个类单元。封装还防止未经授权访问对象的某些部分,从而保护数据不被误用和无意干扰。通常,这是通过使用前导下划线或双下划线将某些属性或方法设为私有来实现的。封装通过公共方法提供受控访问,鼓励模块化并帮助维护对象数据的完整性。

封装的基本概念

  1. 私有属性和方法

    • 使用单个前导下划线 _ 表示“受保护”(protected)属性或方法,通常不应在类外部直接访问。
    • 使用双前导下划线 __ 表示“私有”(private)属性或方法,Python 会对其进行名称改写(name mangling),使其更难以在类外部访问。
  2. 公共方法

    • 提供公共方法来访问和修改私有属性,确保数据的完整性和安全性。

示例

以下是一个展示 Python 封装的示例:

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        self.__balance = balance  # 私有属性

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"Deposited {amount}. New balance: {self.__balance}")
        else:
            print("Deposit amount must be positive.")

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            print(f"Withdrew {amount}. New balance: {self.__balance}")
        else:
            print("Invalid withdrawal amount.")

    def get_balance(self):
        return self.__balance

# 创建 BankAccount 类的对象
account = BankAccount("Alice", 1000)

# 调用公共方法
account.deposit(500)  # 输出: Deposited 500. New balance: 1500
account.withdraw(200)  # 输出: Withdrew 200. New balance: 1300

# 尝试直接访问私有属性(不推荐)
# print(account.__balance)  # 这将引发 AttributeError

# 通过公共方法访问私有属性
print(account.get_balance())  # 输出: 1300

数据抽象(Data Abstraction)

数据抽象是面向对象编程(OOP)的一个重要原则,其目的是隐藏系统的复杂实现细节,只向用户展示必要和相关的信息。数据抽象通过提供简单和直观的接口,有助于提高效率和减少复杂性。它使程序员能够处理简化的系统表示,并管理复杂的操作。在 Python 中,可以使用抽象基类(Abstract Base Classes, ABC)和接口来实现数据抽象。

抽象基类(Abstract Base Classes, ABC)

抽象基类是定义了一组抽象方法的类,这些方法必须由派生类实现。抽象方法是没有具体实现的方法,只有方法签名。通过使用抽象基类,可以确保所有派生类都实现特定的方法,从而保证标准化和一致的交互。

示例

以下是一个使用抽象基类实现数据抽象的 Python 示例:

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

    def perimeter(self):
        return 2 * 3.14 * self.radius

# 创建 Rectangle 和 Circle 对象
rect = Rectangle(10, 20)
circ = Circle(15)

# 访问 area 和 perimeter 方法
print(f"Rectangle Area: {rect.area()}")       # 输出: Rectangle Area: 200
print(f"Rectangle Perimeter: {rect.perimeter()}")  # 输出: Rectangle Perimeter: 60
print(f"Circle Area: {circ.area()}")          # 输出: Circle Area: 706.5
print(f"Circle Perimeter: {circ.perimeter()}")     # 输出: Circle Perimeter: 94.2

详细解释

  1. 定义抽象基类 Shape

    • Shape 类继承自 ABC 类,并定义了两个抽象方法 areaperimeter
    • 抽象方法使用 @abstractmethod 装饰器声明,表示这些方法必须在派生类中实现。
  2. 定义具体类 RectangleCircle

    • Rectangle 类继承自 Shape 类,并实现了 areaperimeter 方法。
    • Circle 类继承自 Shape 类,并实现了 areaperimeter 方法。
  3. 创建对象并调用方法

    • 创建 RectangleCircle 对象。
    • 调用 areaperimeter 方法,计算并输出矩形和圆形的面积和周长。

数据抽象的好处

  1. 隐藏复杂性

    • 通过抽象基类,可以隐藏具体的实现细节,只向用户提供必要的接口。
    • 例如,用户不必了解如何计算矩形和圆形的面积和周长,只需调用相应的方法即可。
  2. 标准化接口

    • 抽象基类确保所有派生类都实现特定的方法,从而提供标准化的接口。
    • 例如,所有形状类都必须实现 areaperimeter 方法,这使得处理不同形状的代码更加一致和简洁。
  3. 提高可维护性

    • 通过数据抽象,代码更加模块化,易于维护和扩展。
    • 例如,如果需要添加新的形状类(如 Triangle),只需实现 areaperimeter 方法,而无需修改现有代码。
  4. 简化交互

    • 用户可以使用相同的接口与不同类型的对象进行交互,而不必了解每个对象的具体实现。
    • 例如,可以编写一个通用函数来处理任何 Shape 对象,而无需关心它是 Rectangle 还是 Circle

总结

面向对象编程的核心概念

  • 继承(Inheritance):允许一个类(子类)继承另一个类(父类)的属性和方法。
  • 多态(Polymorphism):允许不同类的对象被视为单一超类的成员,通过方法重写和重载实现。
  • 封装(Encapsulation):将数据和操作数据的方法绑定在一起,通过私有属性和公共方法保护数据。
  • 数据抽象(Data Abstraction):隐藏系统的复杂实现细节,只向用户展示必要和相关的信息,通过抽象基类和接口实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2232326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

02-Dubbo特性及工作原理

02-Dubbo特性及工作原理 Dubbo 的特性 这里说一下 Dubbo 最主要的特性&#xff0c;从这些特性中&#xff0c;就可以看出来我们为什么要选用 Dubbo&#xff0c;也可以将 Dubbo 和 Spring Cloud 进行对比&#xff0c;比如我们搭建一套微服务系统&#xff0c;出于什么考虑选用 Dub…

通义灵码AI程序员你在用吗?

大家好&#xff0c;我是袁庭新。之前给大家介绍过AI编码助手——通义灵码&#xff0c;这期给大家分享通义灵码AI程序员的一些功能。 随着大模型的持续进化&#xff0c;在语义理解、代码生成、开发工作流等方面的能力也获得了持续、全面的提升。你说&#xff0c;要是有个编程小…

好难的题啊

序&#xff1a; 1.极坐标本质为变化的圆&#xff1a;动曲线---》格林公式 2.曲线积分常见的化简就是对dx&#xff0c;dy进行操作&#xff0c;这要求寻找到合适函数&#xff0c;而极坐标就是天然的函数&#xff08;参数方程&#xff09; 3.重积分--》累次积分--》单独看其中一…

大学适合学C语言还是Python?

在大学学习编程时&#xff0c;选择C语言还是Python&#xff0c;这主要取决于你的学习目标、专业需求以及个人兴趣。以下是对两种语言的详细比较&#xff0c;帮助你做出更明智的选择&#xff1a; C语言 优点&#xff1a; 底层编程&#xff1a;C语言是一种底层编程语言&#x…

开源模型应用落地-Qwen2.5-7B-Instruct与TGI实现推理加速

一、前言 目前&#xff0c;大语言模型已升级至Qwen2.5版本。无论是语言模型还是多模态模型&#xff0c;均在大规模多语言和多模态数据上进行预训练&#xff0c;并通过高质量数据进行后期微调以贴近人类偏好。在本篇学习中&#xff0c;将集成 Hugging Face的TGI框架实现模型推理…

【QT】Qt对话框

个人主页~ Qt窗口属性~ Qt窗口 五、对话框2、Qt内置对话框&#xff08;1&#xff09;Message Box&#xff08;2&#xff09;QColorDialog&#xff08;3&#xff09;QFileDialog&#xff08;4&#xff09;QFontDialog&#xff08;5&#xff09;QInputDialog 五、对话框 2、Qt内…

ubuntu交叉编译expat库给arm平台使用

1.下载expat库源码: https://github.com/libexpat/libexpat/release?page=2 wget https://github.com/libexpat/libexpat/release/download/R_2_3_0/expat-2.3.0.tar.bz2 下载成功: 2.解压expat库,并进入解压后的目录: tar xjf expat-2.3.0.tar.bz2 cd expat-2.3.0 <…

NPOI 操作详解(操作Excel)

目录 1. 安装 NPOI 2. 使用 NPOI 创建新 Excel 文件 3. 设置列宽和行高 1. 设置列宽 2. 设置行高 3. 同时设置列宽和行高 4. 设置统一的行高 5. 设置统一的列宽 6. 应用统一的行高和列宽 4. 合并单元格 5. 设置单元格样式&#xff08;字体、边框、背景色等&#xf…

【Javaee】网络原理-http协议(二)

前言 上一篇博客初步介绍了抓包工具的安装及使用&#xff0c;介绍了http请求报文与响应报文的格式。​​​​​​【Javaee】网络原理—http协议&#xff08;一&#xff09;-CSDN博客 本篇将详细介绍http的方法和http报文中请求头内部键值对的含义与作用&#xff0c;以及常见状…

大模型系列——AlphaZero/强化学习/MCTS

AlphaGo Zero无需任何人类历史棋谱&#xff0c;仅使用深度强化学习&#xff0c;从零开始训练三天的成就已远远超过了人类数千年积累的围棋知识。 1、围棋知识 &#xff08;1&#xff09;如何简单理解围棋知识 &#xff08;2&#xff09;数子法分胜负&#xff1a;https://zhu…

得物多模态大模型在重复商品识别上的应用和架构演进

重复商品治理介绍 根据得物的平台特性&#xff0c;同一个商品在平台上不能出现多个链接&#xff0c;原因是平台需要保证一品一链的特点&#xff0c;以保障商品的集中竞价&#xff0c;所以说一个商品在整个得物平台上只能有一个商详链接&#xff0c;因此我们需要对一品多链的情…

1、DevEco Studio 鸿蒙仓颉应用创建

1. 仓颉鸿蒙应用简介 因为仓颉是静态编译型语言&#xff0c;使用仓颉开发的应用执行效率更高。而且主打全场景&#xff0c;后续可并入仓颉生态&#xff0c;其和ArkTS都是基于ArkUI进行开发&#xff0c;最大的区别是typescript和仓颉语法间的差异。 2. 应用创建 前置条件&…

vue3项目中实现el-table分批渲染表格

开篇 因最近工作中遇到了无分页情景下页面因大数据量卡顿的问题&#xff0c;在分别考虑并尝试了懒加载、虚拟滚动、分批渲染等各个方法后&#xff0c;最后决定使用分批渲染来解决该问题。 代码实现 表格代码 <el-table :data"currTableData"borderstyle"wi…

LeetCode:82. 删除排序链表中的重复元素 II(重复的一个都不保留)

目录 题目描述: 代码: 第一种: 第二种: 题目描述: 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2…

偏差与方差的基本概念

在机器学习中&#xff0c;Bias-Variance Tradeoff&#xff08;偏差-方差权衡&#xff09; 是一个核心概念&#xff0c;帮助我们理解模型的误差来源以及如何调节模型复杂度以达到更好的泛化性能。在这篇博客中&#xff0c;我们将深入讨论什么是偏差和方差&#xff0c;以及如何平…

0-ARM Linux驱动开发-字符设备

一、字符设备概述 Linux 系统中&#xff0c;设备被分为字符设备、块设备和网络设备等。字符设备以字节流的方式进行数据传输&#xff0c;数据的访问是按顺序的&#xff0c;一个字节一个字节地进行读取和写入操作&#xff0c;没有缓冲区。例如&#xff0c;终端&#xff08;/dev…

HTML 基础标签——表格标签<table>

文章目录 1. `<table>` 标签:定义表格2. `<tr>` 标签:定义表格行3. `<th>` 标签:定义表头单元格4. `<td>` 标签:定义表格单元格5. `<caption>` 标签:为表格添加标题6. `<thead>` 标签:定义表格头部7. `<tbody>` 标签:定义表格…

【优选算法】——二分查找!

目录 1、二分查找 2、在排序数组中查找元素的第一个和最后一个位置 3、搜索插入位置 4、x的平方根 5、山脉数组的封顶索引 6、寻找峰值 7、寻找旋转排序数组中的最小值 8、点名 9、完结散花 1、二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组…

东北虎豹国家公园shp格式范围

东北虎豹国家公园地处中国吉林、黑龙江两省交界的老爷岭南部&#xff08;珲春—汪清—东宁—绥阳&#xff09;区域&#xff0c;东起吉林省珲春林业局青龙台林场&#xff0c;与俄罗斯滨海边疆区接壤&#xff0c;西至吉林省大兴沟林业局岭东林场&#xff0c;南自吉林省珲春林业局…

Spring 中的 Environment 对象

可参考官网&#xff1a;Environment Abstraction 核心概念 Environment 对象对两个关键方面进行建模&#xff1a;profiles 和 属性&#xff08;properties&#xff09;。 Profile 简单来说&#xff1a;profile 机制在 IOC 容器中提供了一种机制&#xff1a;允许在不同的环境…