[Python学习篇] Python面向对象——继承

继承是什么

继承是面向对象编程(OOP)中的一个核心概念。继承允许一个类(称为子类或派生类)从另一个类(称为父类或基类)继承属性和方法。这样可以重用代码,提高代码的模块化和可维护性。

  • 父类(基类):提供属性和方法的类。
  • 子类(派生类):继承父类的属性和方法的类。

语法:

class 父类:
    # 父类的属性和方法
    def __init__(self, 属性1):
        self.属性1 = 属性1

    def 方法1(self):
        print("这是父类的方法")


class 子类(父类):
    # 子类的属性和方法
    def __init__(self, 属性1, 属性2):
        super().__init__(属性1)
        self.属性2 = 属性2

    def 方法2(self):
        print("这是子类的方法")
 

示例:

# 定义父类-动物
class Animal:def __init__(self, name):self.name = name# 定义一个空的方法,方法的具体实现由之类重写def speak(self):pass# 定义一个普通方法,子类继承该方法def eat(self):print(f"{self.name} 正在吃饭")# 定义子类-狗
class Dog(Animal):def speak(self):return f"{self.name} 汪汪叫!"# 定义子类-猫
class Cat(Animal):def speak(self):return f"{self.name} 喵喵叫!"# 创建对象并调用方法
dog = Dog("狗")
cat = Cat("猫")print(dog.speak())  # 输出: 狗 汪汪叫!
print(cat.speak())  # 输出: 猫 喵喵叫!dog.eat()  # 输出: 狗 正在吃饭
cat.eat()  # 输出: 猫 正在吃饭

继承的优点

  • 代码重用:子类可以重用父类中的代码,减少重复代码。
  • 模块化:通过继承,可以将通用的功能放在父类中,实现代码模块化。
  • 可扩展性:可以在子类中添加新的功能,而不必修改父类的代码。

多继承

  • 单继承指的是一个类只继承一个父类。子类可以重用父类的属性和方法。
  • 多继承指的是一个类可以继承多个父类,从而获得所有父类的属性和方法。这在某些情况下非常有用,但也可能导致复杂性增加,比如遇到方法解析顺序(MRO)问题。
方法解析顺序(MRO)

在多继承中,方法解析顺序(Method Resolution Order,MRO)决定了在类层次结构中搜索方法和属性的顺序。Python使用C3线性化算法来计算MRO。可以使用__mro__属性或mro()方法来查看类的MRO。

示例:

在这个例子中,D类继承了B和C类,而B和C类又继承了A类。调用d.method()时,按照MRO的顺序,会调用B类的method方法,因为在MRO中B类在C类之前。(继承关系就近原则,D离B最近然后是C然后是A)。

class A:def method(self):print("A method")class B(A):def method(self):print("B method")class C(A):def method(self):print("C method")class D(B, C):passd = D()
d.method()  # 输出: B method
print(D.__mro__)  # 输出: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

子类重写父类的方法和属性

在Python中,子类可以重写父类的同名方法和属性。这意味着子类可以提供自己的实现来覆盖父类中的方法和属性。这样可以使得子类具有独特的行为,同时保留与父类的接口一致性。

  • 重写方法:当子类重写父类的方法时,子类的方法会覆盖父类的方法。在调用该方法时,将执行子类的实现。
  • 重写属性:当子类重写父类的属性时,子类中的属性将覆盖父类中的同名属性。
super() 函数

有时子类需要在重写方法或属性时保留对父类实现的调用。可以使用 super() 函数来调用父类的方法。

示例:

# 父类
class Parent:def greet(self):return "父类"# 子类
class Child(Parent):def greet(self):# 带参数的写法,写法一# parent_greeting = super(Child, self).greet()# 不带参数的写法,写法二parent_greeting = super().greet()return f"{parent_greeting} 和 子类"child = Child()
print(child.greet())  # 输出: 父类 和 子类

重写和重载

  • 重写

重写指的是子类重新定义父类中的方法或属性。通过重写,子类可以提供自己的实现来替换父类的实现。重写主要用于多态性和定制子类行为。

  • 重载 

重载指的是在同一个作用域中定义多个具有相同名字但参数不同的方法。在许多编程语言中(例如C++和Java),重载是允许的,编译器会根据方法签名(参数的数量和类型)来区分它们。然而,在Python中,方法重载并不直接支持。Python中的函数或方法如果使用相同的名字,后面的定义会覆盖前面的定义。

尽管如此,Python可以通过默认参数和可变参数来实现类似重载的效果。

私有权限

在Python中,私有权限(Private Access)用于限制类属性和方法的访问,即私有属性和私有方法。使其只能在类内部使用。这是通过命名约定和名称改写(name mangling)机制来实现的。

_ 单下划线 (受保护)

单下划线前缀表示“受保护的”变量或方法。这是一种约定,表示这些变量或方法不应该不推荐在类外部直接使用,虽然它们仍然可以被访问。

示例:

class Hello:def __init__(self):self._protected_var = "我是受保护的属性"def _protected_method(self):return "我是受保护的方法"hello = Hello()
# 依然可以访问到,但是不推荐不应该访问
print(hello._protected_var)          # 输出:我是受保护的属性
print(hello._protected_method())     # 输出:我是受保护的方法
__ 双下划线 (私有)

双下划线前缀用于实现名称改写(name mangling),使得属性或方法在类外部无法轻易访问。Python会将这些名称改写为 _ClassName__variableName 的形式,从而实现基本的私有化。

示例:

get 私有属性

class Hello:__private_var = "我是私有的属性"def __private_method(self):return "我是私有的方法"# 用于访问私有属性def get_private_var(self):return self.__private_var# 用于访问私有方法def get_private_method(self):return self.__private_method()hello = Hello()
# 以下访问会报错
# print(hello.__private_var)      # 出异常 AttributeError
# print(hello.__private_method()) # 出异常 AttributeError# 方式一:
# 通过类内部方法间接访问
print(hello.get_private_var())          # 输出:我是私有的属性
print(hello.get_private_method())       # 输出:我是私有的方法# 方式二:
# 通过名称改写访问,改写规则是 `_类名__变量方法名`
print(hello._Hello__private_var)        # 输出:我是私有的属性
print(hello._Hello__private_method())   # 输出:我是私有的方法

set 私有属性

class Hello:__private_var = "20"# 获取私有属性值def get_private_var(self):return self.__private_var# 修改私有属性值def set_private_var(self, __private_var):self.__private_var = __private_varhello = Hello()# 获取修改前的数据
print(hello.get_private_var())  # 20# 修改数据
hello.set_private_var("10")# 获取修改后的数据
print(hello.get_private_var())  # 10
私有权限对于继承的影响
  • 私有属性和方法:在子类中无法直接访问父类的私有属性和方法。这是因为它们被名称改写,只有通过父类提供的公有方法间接访问。例如,通过get_private_var()可以访问父类的私有成员。

  • 受保护属性和方法:子类可以直接访问和调用父类的受保护属性和方法,因为单下划线只是一个约定,而不是严格的访问控制。

  • 公有属性和方法:子类可以直接访问和调用父类的公有属性和方法。

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

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

相关文章

js面试题2024

1.js的数据类型 boolean number string null undefined bigint symbol object 按存储方式分&#xff0c;前面七种为基本数据类型&#xff0c;存储在栈上&#xff0c;object是引用数据类型&#xff0c;存储在堆上&#xff0c;在栈中存储指针 按es标准分&#xff0c;bigint 和sym…

PHP框架讲解 - symfony框架

Symfony 框架概述 Symfony 是一个用于构建 web 应用的 PHP 框架&#xff0c;它遵循 MVC&#xff08;模型-视图-控制器&#xff09;模式&#xff0c;并且具有高度的可定制性。Symfony 是一个组件库&#xff0c;它提供了许多用于构建现代 web 应用的工具和功能。以下是对 Symfon…

布隆过滤器 redis

一.为什么要用到布隆过滤器&#xff1f; 缓存穿透&#xff1a;查询一条不存在的数据&#xff0c;缓存中没有&#xff0c;则每次请求都打到数据库中&#xff0c;导致数据库瞬时请求压力过大&#xff0c;多见于爬虫恶性攻击因为布隆过滤器是二进制的数组&#xff0c;如果使用了它…

FLD工作日志

在FLD的工作日志 一、技能掌握杨总经验的传输 一、技能掌握 06.12 学会如何看小产品的代码&#xff0c;看的消毒灯 07.08 1.学会嘉立创eda 杨总经验的传输 07.07 什么能做就做什么&#xff0c;一刻也不要停不要看不起简单的事情&#xff0c;量变引起质变

科普文:K8S中常见知识点梳理

简单说一下k8s集群内外网络如何互通的 要在 Kubernetes&#xff08;k8s&#xff09;集群内外建立网络互通&#xff0c;可以采取以下措施&#xff1a; 使用service&#xff1a; 使用Service类型为NodePort或LoadBalancer的Kubernetes服务。这可以使服务具有一个公共IP地址或端口…

怎么发顶会论文

AI顶会论文成功发表路径四&#xff1a;写作关_哔哩哔哩_bilibili 全集都有&#xff0c;随手记录一下。 讲的很好&#xff0c;我多努力。努力靠近一下。

Open3D 计算点云的平均密度

目录 一、概述 1.1基于领域密度计算原理 1.2应用 二、代码实现 三、实现效果 2.1点云显示 2.2密度计算结果 一、概述 在点云处理中&#xff0c;点的密度通常表示为某个点周围一定区域内的点的数量。高密度区域表示点云较密集&#xff0c;低密度区域表示点云较稀疏。计算…

Redis连接Resp图形化工具和springboot

Redis连接Resp图形化工具和springboot 1.redis配置1.1 备份、修改conf文件1.2 Redis的其它常见配置&#xff1a;1.3 启动Redis&#xff1a;1.4 停止服务&#xff1a;1.5 开机自启&#xff1a; 2. resp的安装、配置和连接&#xff1a;2.1 GitHub上下载2.2 开始连接redis ![在这里…

Java 集合框架:Java 中的 Set 集合(HashSet LinkedHashSet TreeSet)特点与实现解析

大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 017 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自…

运营商二三要素是什么?有什么意义

运营商的二要素和三要素通常指的是在用户身份验证过程中所使用的关键信息。这些要素在保障用户信息安全、防止诈骗犯罪、维护社会秩序等方面具有重要意义。 运营商二要素 运营商二要素指的是在身份验证过程中&#xff0c;需要验证的两个关键信息&#xff0c;通常是&#xff1a…

C++初探究

概述 C可以追溯到1979年&#xff0c;C之父Bjarne Stroustrup在在使用C语言研发工作时发现C语言的不足&#xff0c;并想要将其改进&#xff0c;到1983年&#xff0c;Bjarne Stroustrup在C语言的基础上添加了面向对象编程的特性&#xff0c;设计出了C的雏形。 网址推荐 C官方文…

Docker:WARNING: Published ports are discarded when using host network mode 解决方法

在Docker中&#xff0c;使用主机网络模式&#xff08;host network mode&#xff09;时&#xff0c;容器将共享主机的网络命名空间&#xff0c;这意味着容器将直接使用主机的网络接口和端口。因此&#xff0c;当你尝试通过Docker的发布端口功能&#xff08;publish a port&…

如何在uniapp中使用websocket?

websocket是我们经常使用到的接口,通常用于即时通讯以及K线图这种需要实时更新数据的业务需求上,传统的restful接口虽然可以满足,但是你需要轮询,这就要额外写一堆代码,不是很方便,用websocket就简单很多,我们来看代码 第一步定义全局常量、变量 const config = {host…

ActiViz实战:ActiViz实现体绘制裁剪

文章目录 效果预览关键代码源码地址效果预览 ActiViz体绘制裁剪 关键代码 1、实现体绘制 FolderBrowserDialog folderDialog = new FolderBrowserDialog(); folderDialog.SelectedPath = "E:\\S100"; string

王老师 linux c++ 通信架构 笔记(三)安装 xftp、

&#xff08;11&#xff09;调整 xshell 终端的字体大小&#xff0c;默认字体大小是 9 &#xff1a; &#xff08;12&#xff09; 共享文件夹 hgfs 的含义&#xff1a; &#xff08;13&#xff09;安装 xftp &#xff0c; 傻瓜式安装&#xff0c;出了修改下默认安装位置。 操作…

.locked勒索病毒解析与防护指南

引言 随着信息技术的飞速发展&#xff0c;网络安全问题日益严峻&#xff0c;其中勒索病毒成为威胁企业和个人数据安全的重要隐患之一。在众多勒索病毒家族中&#xff0c;.locked勒索病毒以其独特的加密方式和广泛的传播途径&#xff0c;引起了广泛的关注。本文将从多个方面详细…

使用redis-cli查找大key

执行命令 涉及redis-cli 连接和登录&#xff0c;请查看&#xff1a;Redis-cli 连接Redis-CSDN博客 redis-cli -h <redis_instance_address> -p <port> -a <password> --bigkeys<redis_instance_address>&#xff1a; Redis 实例的 IP 地址。 <p…

opencv 鱼眼图像的矫正(动态参数调整)

一&#xff1a;棋盘校准参数说明(内参) 棋盘校准的方法及代码很多&#xff0c;参见其他连接 1&#xff1a;内参矩阵 2&#xff1a;畸变系数 针对鱼眼相机此处是4个参数&#xff0c;在其校准代码中也可以知道&#xff0c;其通常的定义如下&#xff1a; data.camera_mat np.e…

报修小程序论文(设计)开题报告

一、课题的背景和意义 近些年来&#xff0c;随着移动互联网巅峰时期的来临&#xff0c;互联网产业逐渐趋于“小、轻、微”的方向发展&#xff0c;符合轻应用时代特点的各类技术受到了不同领域的广泛关注。在诸多产品中&#xff0c;被誉为“运行着程序的网站”之名的微信小程序…

uniapp-小程序获取用户位置

1. 需要在微信公众平台进行接口的申请。选择自己需要用的接口。 2. 在app.json文件中配置permission和requiredPrivateInfos。requiredPrivateInfos里面是你需要使用的接口。 3. 配置完成后&#xff0c;就可以使用了。 相关获取位置API的链接 4. 如果要获取当前位置到某一个指…