Python:继承

注意:本文引用自专业人工智能社区Venus AI

更多AI知识请参考原站 ([www.aideeplearning.cn])

Python中的继承是面向对象编程(OOP)的一个基本特性,它允许一个类(称为子类)继承另一个类(称为父类或基类)的属性和方法。这里是关于Python继承的一些关键点:

基本概念

  1. 父类(基类):父类是被继承的类,它提供了子类可以继承的属性和方法。
  2. 子类(派生类):子类是从一个或多个父类继承属性和方法的类。

继承的优势

  1. 代码重用:继承允许子类重用父类的代码,这减少了代码的重复编写。
  2. 封装性:子类可以添加自己独特的属性和方法,同时继承父类的功能。
  3. 多态性:子类可以覆盖或修改父类的行为,这是面向对象编程中多态性的一个体现。

继承类型

  1. 单继承:子类只继承一个父类。这是最简单的继承形式。
  2. 多继承:子类可以继承多个父类。Python 支持多继承,这使得子类可以同时从多个基类继承属性和方法。

方法重写

子类可以重写继承自父类的方法。这意味着子类可以提供父类方法的一个特定于子类的新实现。

super() 函数

super() 函数在继承中发挥重要作用,它用于调用父类的方法。它特别在多继承场景中非常有用,可以正确地处理方法调用,遵循方法解析顺序(MRO)。

方法解析顺序(MRO)

MRO 是一个规则集,它决定了 Python 在多继承场景下如何搜索继承的方法。Python 使用一种称为 C3 线性化的算法来确定这个顺序,确保每个基类仅被访问一次,并且保持基类之间的适当顺序。

使用继承

在设计程序时,继承应谨慎使用。不恰当的使用可能导致代码难以理解和维护。一般建议,只有在子类确实是父类的一种特殊形式时,才使用继承。

继承是Python面向对象编程的核心特性之一,提供了强大的代码组织和重用机制。正确使用继承可以使代码更加清晰、灵活和可维护。

代码详细示例

1.继承的概念

在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承的概念就要简单得多了,即描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承自狗。代码如下:

#lei.py
# 定义一个父类,如下:    
class Cat( ):    def __init__(self, name, color ):    self.name = name    self.color = color    def run(self):    print("%s--在跑" %self.name)    
# 子类在继承的时候,在定义类时,小括号()中为父类的名字,继承Cat类如下:    
class TianyuanCat(Cat):    def setNewName(self, newName):    self.name = newName   print(self.name)def eat(self):    print("%s--在吃"%self.name)    
Xuanmao = TianyuanCat("玄猫", "黑色")    
print('Xuanmao的名字为:%s' %Xuanmao.name)    
print('Xuanmao的颜色为:%s' %Xuanmao.color)    
Xuanmao.eat()    
Xuanmao.setNewName('小黑')  
Xuanmao的名字为:玄猫
Xuanmao的颜色为:黑色
玄猫--在吃
小黑虽然子类TianyuanCat没有定义初始化方法和run方法,但是父类(Cat)有,所以在子类继承父类的时候这个方法就被继承了,所以只要创建TianyuanCat的对象,就默认执行了那个继承过来的init()方法了。
此外,还需要注意的是:
(1)类的私有的属性,不能通过对象直接访问,但是可以通过方法访问。
(2)私有的方法不能通过对象直接访问。
(3)私有的属性、方法不会被子类继承,也不能被访问。
(4)一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用。
代码如下:
#lei.py
class Animal():    def __init__(self, name='动物', color='白色'):    self.__name = name    self.color = color    def __test(self):    print(self.__name)    print(self.color)    def test(self):    print(self.__name)    print(self.color)    
class Dog(Animal):    def dogTest1(self):    #print(self.__name) #不能访问到父类的私有属性    print(self.color)    def dogTest2(self):    #self.__test() #不能访问父类中的私有方法    self.test()    
A = Animal()    
#print(A.__name) #程序出现异常,不能访问私有属性    
print(A.color)    
#A.__test() #程序出现异常,不能访问私有方法    
A.test()    
print("------分割线-----")    
D = Dog(name = "小花狗", color = "黄色")    
D.dogTest1()    
D.dogTest2() 
白色
动物
白色
------分割线-----
黄色
小花狗
黄色

 

2.多继承

所谓多继承,即子类有多个父类,并且具有它们的特征,如下图所示。 Python中的多继承代码如下:

#lei.py
# 定义一个父类    
class A:    def printA(self):    print('----A----')    
# 定义一个父类    
class B:    def printB(self):    print('----B----')    
# 定义一个子类,继承自A、B    
class C(A,B):    def printC(self):    print('----C----')    
obj_C = C()    
obj_C.printA()    
obj_C.printB()
obj_C.printC() 
----A----
----B----
----C----

注意一点,如果在上面的多继承例子中,如果父类A和父类B中,有一个同名的方法,那么通过子类去调用的时候,调用先继承的父类方法。代码如下:

#lei.py
class base(object):    def test(self):    print('----base test----')    
class A(base):    def test(self):    print('----A test----')    
# 定义一个父类    
class B(base):    def test(self):    print('----B test----')    
# 定义一个子类,继承自A、B    
class C(A,B):    pass    
obj_C = C()    
obj_C.test()    
#输出:----B test----
----A test----

3. 调用与重写父类方法

所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法,代码如下:

#lei.py
class Cat:    def sayHello(self):    print("miaomiao~~")    
class Xuanmao(Cat):     def sayHello(self):    print("miao!~~!!!")    
xiaohei = Xuanmao()    
xiaohei.sayHello()
#输出:miao!~~!!!
miao!~~!!!


在类的继承里面super()方法是很常用的,它解决了子类调用父类方法的一些问题,例如,当父类多次被调用时只执行一次,优化了执行逻辑,下面我们来详细看一下。
当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,代码如下:

#lei.py
class Cat1:    def sayHello(self):    print("miaomiao~~")    
class Xuanmao(Cat):     def sayHello(self):    # 调用父类方法事,直接使用父类名称进行调用    Cat1.sayHello(self)    
xiaohei = Xuanmao()     
xiaohei.sayHello() 
#输出:miaomiao~~
miaomiao~~

当使用继承时,一个子类会继承父类的属性和方法。但如果直接在子类中通过父类的名称来调用父类的构造函数或方法,就会面临一些限制和问题:

父类名称修改:如果更改了父类的名称,那么所有子类中的相关代码也必须跟着更改。这在大型项目中,尤其是子类众多时,会导致维护成本显著增加。

多继承的复杂性:Python支持多继承,即一个子类可以有多个父类。在多继承的情况下,如果子类需要调用所有父类的方法,那么使用传统的方式就需要明确地重复每个父类的名称,这增加了代码的复杂性和冗余。

为了解决这些问题,Python提供了super()函数。如下示例所示

#lei.py
class Cat2321:    def sayHello(self):    print("miaomiao~~")    
class Xuanmao(Cat):     def sayHello(self):    # 使用super()代替父类类名,即便类名改变,这里的super也不需要修改。    super().sayHello()    
xiaohei = Xuanmao()     
xiaohei.sayHello()  
#输出:miaomiao~~
miaomiao~~

使用super()可以带来以下优势:

简化代码:super()允许你不必显式地引用父类,这使得代码更加简洁、易于理解和维护。

自动解析正确的方法:在多继承的情况下,super()知道应该调用哪个父类的方法,遵循所谓的方法解析顺序(MRO)。这减少了多继承时潜在的复杂性和错误。

动态继承:super()的动态特性意味着你不需要硬编码父类的名称,使得代码更加灵活。如果父类发生变化,子类的代码不需要修改。

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

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

相关文章

string c++

#include<iostream> using namespace std; int main() { string a"wddw"; string b"wdwdwdwdwd"; string c b a; cout << c << endl; cout << c.length() << endl; string c_sub c.substr(2,2);//从第二个开…

day10_面向对象之封装丶构造器

封装概述 现实生活中&#xff0c;每一个个体与个体之间是有边界的&#xff0c;每一个团体与团体之间是有边界的&#xff0c;而同一个个体、团体内部的信息是互通的&#xff0c;只是对外有所隐瞒。 面向对象编程语言是对客观世界的模拟&#xff0c;客观世界里每一个事物的内部…

【MySQL】巧解客户连续递增交易

力扣题 1、题目地址 2701. 连续递增交易 2、模拟表 表&#xff1a;Transactions 字段名类型transaction_idintcustomer_idinttransaction_datedateamountint transaction_id 是该表的主键。每行包含有关交易的信息&#xff0c;包括唯一的 (customer_id, transaction_date…

总结: HQL语句

总结: HQL语句 Part1 数据库的操作Part2 数据表的操作1. 创建普通表2. 内外部表3. 内外部表转换 Part1 数据库的操作 查看数据库: show databases; 创建数据库: create database if not exists 数据库名 使用数据库: use 数据库名; 查看数据库详细信息: desc database 数据库名…

Echarts 利用多X轴实现未来15天天气预报

Echarts 利用多X轴实现未来15天天气预报 UI 设计图 Echarts 实现效果 代码实现 代码分解 echarts 图表上下均显示数据 通过设置 grid.top 和 grid.bottom 设置白天和夜间天气展示区域 grid: {top: 36%,bottom: 36%,left: 5%,right: 5%}, 天气图标的设置 由于 axisLabel 的…

【Linux】一文了解【进程优先级相关知识点】&【PRI / NI值】背后的修正原理(13)

前言 大家好吖&#xff0c;欢迎来到 YY 滴Linux系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《…

算法 之 排序算法

&#x1f389;欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨ &#x1f389;感谢各位读者在百忙之中抽出时间来垂阅我的文章&#xff0c;我会尽我所能向的大家分享我的知识和经验&#x1f4d6; &#x1f389;希望我们在一篇篇的文章中能够共同进步&#xff01;&#xff01;&…

实验7-2-10 简易连连看(PTA)

题目&#xff1a; 本题要求实现一个简易连连看游戏模拟程序。 给定一个2N2N的方阵网格游戏盘面&#xff0c;每个格子中放置一些符号。这些符号一定是成对出现的&#xff0c;同一个符号可能不止一对。程序读入玩家给出的一对位置(x1​,y1​)、(x2​,y2​)&#xff0c;判断这两…

leetcode(Hot100)——数组篇

1、两数之和 本题使用哈希法&#xff0c;用一个哈希Map保存数组的值以及对应下标&#xff0c;代码如下&#xff1a; class Solution {public int[] twoSum(int[] nums, int target) {HashMap<Integer,Integer> map new HashMap<>();for(int i0; i<nums.length…

【网络基础】网络层基本协议介绍

目录 一、IP数据包 1.1 网络层的功能 1.2 IP数据包格式 二、ICMP协议介绍 2.1 作用 2.2 常用命令 2.2.1 Ping命令 2.2.2 tracert命令 2.3 广播域 三、ARP协议介绍 3.1 作用 3.2 原理 一、IP数据包 1.1 网络层的功能 定义了基于IP协议的逻辑地址&#xff0c;就是I…

数据结构应用——哈夫曼树

哈夫曼树 哈夫曼树的相关概念构造哈夫曼树基础算法 哈夫曼编码 哈夫曼树的相关概念 结点的权&#xff1a;有某种现实含义的数值。结点的带权路径长度&#xff1a;从树的根结点到该结点的路径长度&#xff08;经过的边数&#xff09;与该结点上权值的乘积。树的带权路径长度&am…

CAPL (Communication Access Programming Language)

CAPL (Communication Access Programming Language) 是一种专门用于模拟和测试汽车网络的脚本语言&#xff0c;特别是CAN (Controller Area Network) 和LIN (Local Interconnect Network) 网络。虽然CAPL主要用于模拟网络行为和测试网络节点&#xff0c;但它也支持一些基本的编…

XiBe希贝奶瓶好用吗?2名宝宝的宝爸深度测评分享!

几乎每个新手宝爸宝妈都会有一段时间对孩子的很多东西都是不懂的&#xff0c;一边摸索一边学习。列如关于奶瓶这个问题就困扰不少新手爸妈&#xff0c;特别是面对这么多的品牌的奶瓶完全不知道怎么选。 相信很多新手爸妈都十分担心奶瓶材质安全问题&#xff0c;所以我作为一名…

OpenCV+OpenCV-Contrib源码编译

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、OpenCV是什么&#xff1f;二、OpenCV 源码编译1.前期准备1.1 源码下载1.2 cmake安装1.3 vscode 安装1.4 git 安装1.5 mingw安装 2.源码编译2.1 打开cmake2.…

python(django)之流程接口管理后台开发

1、在models.py中加入流程接口表和单一接口表 代码如下&#xff1a; from django.db import models from product.models import Product# Create your models here.class Apitest(models.Model):apitestname models.CharField(流程接口名称, max_length64)apitester model…

Python学习笔记07

第十三章&#xff0c;面向对象 初识对象 生活中数据的组织 学校开学&#xff0c;要求学生填写自己的基础信息&#xff0c;一人发一张白纸&#xff0c;让学生自己填 我叫林军杰&#xff0c;今年31岁.来自山东省&#xff0c;我是男的&#xff0c;中国人 内容混乱 改为登记表…

详细分析Python中的enumerate()函数(附多个Demo)

目录 前言1. 基本知识2. Demo 前言 对于Python的基本函数&#xff0c;从实战中获取确切知识 1. 基本知识 enumerate() 接受一个可迭代对象作为输入&#xff0c;并返回一个枚举对象这个枚举对象包含了原始可迭代对象中的每个元素以及对应的索引它允许在循环中同时获取索引和值…

uboot - pinctrl - FPGA回片前测试阶段 - 设置GPIO引脚复用失败

问题描述 pinctrl设置引脚复用失败&#xff0c;没有调用到controller中的set_groups_function函数。 问题定位 pinctrl如何注册dm节点如何进行设备树中各个设备节点下的复用配置为什么没调用到控制器实现的set_groups_function函数 &gpio0 {status "okay";p…

Flutter插件开发与发布指南

在Flutter应用程序开发中&#xff0c;有时候我们会遇到需要使用原生功能的情况&#xff0c;这时候就需要编写Flutter插件来实现与原生平台的交互。本篇博客将介绍如何编写、发布和使用Flutter插件。 1. 准备工作 在开始之前&#xff0c;确保你已经安装好Flutter开发环境&…

JavaScript中改进的数组功能

ES6标准为数组添加了很多新功能&#xff0c;例如&#xff0c;创建数组的新方法&#xff0c;创建定型数组&#xff08;Typed Array)的能力等。 1、创建数组 在ES6以前&#xff0c;创建数组的方式主要有两种&#xff0c;一种是调用Array构造函数&#xff0c;另一种是用数组字面…