继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,新建的类可称为子类或派生类,父类又可称为基类或超类
通过类的内置属性__bases__可以查看类继承的所有父类
补充 :
要找出类与类之间的继承关系,需要先抽象,再继承。抽象即总结相似之处,总结对象之间的相似之处得到类,总结类与类之间的相似之处就可以得到父类,如下图所示
基于抽象的结果,我们就找到了继承关系
基于上图我们可以看出类与类之间的继承指的是什么’是’什么的关系(比如人类,猪类,猴类都是动物类)。子类可以继承/遗传父类所有的属性,因而继承可以用来解决类与类之间的代码重用性问题。比如我们按照定义Student类的方式再定义一个Teacher类
类Teacher与Student之间存在重复的代码,老师与学生都是人类,所以我们可以得出如下继承关系,实现代码重用
Teacher类内并没有定义__init__方法,但是会从父类中找到__init__,因而仍然可以正常实例化,如下
这整个的过程就是我们平常写代码 , 怎么样写出来继承的 , 先分开写类 , 然后有重复的代码 , 归纳到父类中继承
有了继承关系,对象在查找属性时,先从对象自己的__dict__中找,如果没有则去当前类中找,然后再去父类中找
父类如果不想让子类覆盖自己的方法,可以采用双下划线开头的方式将方法设置为私有的
关于多继承下的属性查找 , 会涉及到菱形问题 , 以及python多继承的优缺点 , 和mixins机制 , 下面单独具体介绍
大多数面向对象语言都不支持多继承,而在Python中,一个子类是可以同时继承多个父类的,这固然可以带来一个子类可以对多个不同父类加以重用的好处,但也有可能引发著名的 Diamond problem菱形问题(或称钻石问题,有时候也被称为“死亡钻石”),菱形其实就是对下面这种继承结构的形象比喻
这种继承结构下导致的问题称之为菱形问题:如果A中有一个方法,B和/或C都重写了该方法,而D没有重写它,那么D继承的是哪个版本的方法:B的还是C的?如下所示
python到底是如何实现继承的呢? 对于你定义的每一个类,Python都会计算出一个方法解析顺序(MRO)列表,该MRO列表就是一个简单的所有基类的线性顺序列表,如下
python会在MRO列表上从左到右开始查找基类, 直到找到第一个匹配这个属性的类为止。 而这个MRO列表的构造是通过一个C3线性化算法来实现的
如果继承关系为菱形结构,那么经典类与新式类会有不同MRO,分别对应属性的两种查找方式:深度优先和广度优先
小结
一个子类可以同时继承多个父类,这样的设计常被人诟病,一来它有可能导致可恶的菱形问题,二来在人的世界观里继承应该是个”is-a”关系。 比如轿车类之所以可以继承交通工具类,是因为基于人的世界观,我们可以说:轿车是一个(“is-a”)交通工具,而在人的世界观里,一个物品不可能是多种不同的东西,因此多重继承在人的世界观里是说不通的,它仅仅只是代码层面的逻辑。不过有没有这种情况,一个类的确是需要继承多个类呢?
答案是有,我们还是拿交通工具来举例子:
民航飞机、直升飞机、轿车都是一个(is-a)交通工具,前两者都有一个功能是飞行fly,但是轿车没有,所以如下所示我们把飞行功能放到交通工具这个父类中是不合理的
但是如果民航飞机和直升机都各自写自己的飞行fly方法,又违背了代码尽可能重用的原则(如果以后飞行工具越来越多,那会重复代码将会越来越多)。
怎么办???为了尽可能地重用代码,那就只好在定义出一个飞行器的类,然后让民航飞机和直升飞机同时继承交通工具以及飞行器两个父类,这样就出现了多重继承。这时又违背了继承必须是”is-a”关系。这个难题该怎么解决?
python提供了Mixins机制,简单来说Mixins机制指的是子类混合(mixin)不同类的功能,而这些类采用统一的命名规范(例如Mixin后缀),以此标识这些类只是用来混合功能的,并不是用来标识子类的从属"is-a"关系的,所以Mixins机制本质仍是多继承,但同样遵守”is-a”关系,如下
简单总结 : 多继承中遇到混合继承 , 那么就采用Mixins机制解决 , 注意这不是语法严格要求的 , 这是约定俗成的
使用Mixin类实现多重继承要非常小心
子类可以派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父类被查找 , 那么在子类派生的新方法中如何重用父类的功能???
方式1: 指名道姓调用某一类下的函数=>不依赖继承关系
方式2: super()调用父类提供给自己的方法=>严格继承关系
super方法会在后面我们重写父类方法的时候必须先加上这一行代码 , 为的是不破坏原来父类中该方法的代码 , 我们只是重用并新增一些代码 , 即在原来的基础上追加
在一个类中以另外一个类的对象作为数据属性,称为类的组合。就是把对象当成属性
组合与继承都是用来解决代码的重用性问题。不同的是:继承是一种“是”的关系,比如老师是人、学生是人,当类之间有很多相同的之处,应该使用继承;而组合则是一种“有”的关系,比如老师有生日,老师有多门课程,当类之间有显著不同,并且较小的类是较大的类所需要的组件时,应该使用组合,如下示例
此时对象teacher1集对象独有的属性、Teacher类中的内容、Course类中的内容于一身(都可以访问到),是一个高度整合的产物
1、继承是指函数之间相同性很高时,可以采取从基类(父类)继承相同的部分,形成派生类(子类)。如图:可以将三者相同部分写成一个函数然后分别继承2、继承方式三种:public,private,protected3、总结:1、基类private成员在派生类中无论以什么方式继承均不可见(在类外与类内均不能直接访问);2、基类的私有成员在子类均不可见,基类的其他成员在子类的访问方式取权限小的;public&
python继承
main方法能重载么?main方法能被其他方法调用么?main方法可以继承么?我们一开始学习 Java 程序的时候,最先跑的一段代码肯定是 main 方法,main 方法的格式如下:public static void main(String[] args) {}那么 main 方法有什么特殊的地方呢?今天我们来简单看一下。首先针对 main 方法的格式定义:「publi
继承 :继承是一个关于 构造函数 的高阶应用继承一定是出现在 两个构造函数 之间的
一、基类与派生类的概念基类(父类):在继承关系中处于上层的类 派生类(子类):在继承关系中处于下层的类class A;class B;class C:public A //C为A的子类,A为C的父类{};class D:public A,public B //D为A和B的子类,A和B均为D的父类{};二、类派生列表派生类通过派生类列表来指出其从哪个(哪些)基...
继承实际上是存在于面向对象程序设计中的两个类之间的一种关系,是面向对象程序设计方法的一个重要手段,通过继承可以更有效地组织程序结构,明确类间的关系,充分利用已有的类来完成更复杂、更深入的开发。当一个类拥有另一个类的所有数据和操作时,就称这两个类之间具有继承关系。被继承的类称为父类或超类,继承了父类或超类的所有数据和操作的类称为子类。在Java语言程序设计类头定义中用extends表明子类与父类
实验3:权限的继承,取消继承,强制继承实验目标继承:在e:\tom文件夹上添加tom用户读和写的权限,在e:\tom文件夹下创建子文件夹,查看子文件夹的NTFS权限tom用户是否具有读写权限取消继承:保留子文件夹tom用户的NTFS权限为读,取消上级文件夹继承的写权限强制继承:在父文件夹tom文件夹上配置强制继承实验环境略实验步骤一、 在e:\tom文件夹上添加tom用户读和写的权限右击
# TypeScript中的多重继承TypeScript 是一种为 JavaScript 提供静态类型的语言。它支持面向对象的编程,包括类和继承。但与某些其他编程语言(如 C++ 和 Python)不同,TypeScript 不支持多重继承。在 TypeScript 中,如果需要实现多重继承的效果,通常会用以下几种方式:接口、混入(mixins)、以及组合模式。## 1. TypeScri
一、多继承1、多继承基本语法2、多继承子类构造初始化3、多继承中访问父类成员二、多继承案例1、代码示例 - 简单多继承案例2、代码示例 - 多继承构造函数案例
一、继承简介1、继承概念2、继承语法3、单继承与多继承二、代码示例1、代码示例 - 单继承2、代码示例 - 多继承
一个子类继承父类时,可按照public、private和protected方式继承父类,每种继承方式的区别如下: 1) public继承方式基类中所有public成员在派生类中为public属性; 基类中所有protected成员在派生类中为protected属性; 基类中所有private成员在派生类中不可访问。 2) protected继承方式基类中的所有...
多重继承的特性和使用和单继承没区别。按照单继承来使用即可。多重继承可能会引入一个“菱形继承的问题”,这个问题其实并不算问题,因为它合情合理
学无止尽,积土成山,积水成渊-《C++反汇编与逆向分析技术揭秘》 读书笔记。马上就要出差了,回来后接着写吧。一、概述 菱形继承是最复杂的对象结构,菱形结构会将单一继承与多重继承进行组合。菱形继承示意如下:class A;class B : virtual public A;class C : virtual public A;class D : public B, public C;
文中“实现”一词特指接口的继承。一个类实现多个接口时,不能出现同名的默认方法。一个类既要实现接口又要继承抽象类,先继承后实现。一个抽象类可以继承多个接口(implements),一个接口却不可以继承抽象类,一个接口可以用(extends)继承多个接口。接口中默认方法加default,抽象方法abstract可省略,数据成员必须赋初值,final可省略。接口的作用是制定标准,一个各方都需要遵守的守则
练习 回合制对战游戏:奥特曼A和小怪兽A进行PK,直到一方的血量为0时结束战斗,输出谁胜利了! 如果奥特曼A胜利,则奥特曼A和奥特曼B进行Pk,直到一方的血量为0时结束战斗,输出谁胜利了! 如果小怪兽A胜利,则小怪兽A和小怪兽B进行Pk,直到一方的血量为0时结束战斗,输出谁胜利了! 首先要弄清楚奥特曼A与奥特曼B是父类与子类的关系,所以子类是可以继承到父类所有的(任何访问修饰符的属性和
两个派生类继承同一个基类而又有某个类同时继承者两个派生类,这种继承被称为菱形继承,或者钻石型继承。 这种继承所带来的问题: 羊继承了动物的数据和函数,鸵同样继承了动物的数据和函数,当草泥马调用函数或者数据时,就会产生二义性。 草泥马继承自动物的函数和数据继承了两份,其实我们应该清楚,这份数据我们只需 ...
class BaseA{}; class BaseB{}; 多继承:class C :public BaseA,Public BaseB{}; 虚继承:class D:virtual public BaseA{};
引言 在JavaScript中,实现继承的主要方式是通过原型链技术。这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴。原型链介绍 原型链作为JS实现继承的主要方式,其基本思想是:利用原型让一个引用类型继承另一个引用类型的属性和方法。我们可以简单回顾下构造函数、原型对象和实例对象之间的关系。每一个构造函数都有一个指向原型对象的指针
如何解读IL代码 关于IL代码,我有将从三个方面去揭开它神秘的面纱。IL代码是什么?我们为什么要去读懂IL代码?我们如何去读懂IL代码?这三个问题的解答,将是我解读IL代码的整体思路。 IL代码是什么?IL(Intermediate Language),它也称为CIL或者MSIL,翻译成中文就是“中间语言”。C#的JIT编译器可以将C#
etcd集群架构摘要 etcd集群采用Raft一致性协议实现高可用和强一致性,核心架构包含: 节点角色 Leader:处理写请求、日志复制 Follower:接收Leader指令、参与选举 Candidate:选举过渡状态 数据分布 写请求通过Leader协调,并行复制到多数节点后提交 读请求支持线性化读和过期读两种模式 故障处理 心跳机制检测节点存活 选举机制自动选主 日志复制确保数据一致性 集群通过负载均衡器分发请求,各节点独立存储数据并定期备份,形成完整的分布式键值存储解决方案。
传统的大语言模型采用的训练目标是 Next-Token Prediction (NTP),即在位置 t 上预测下一个 token (t+1)。而 Multi-Token Prediction (MTP) 的核心思想在于: 不仅预测下一个 token,而是能够同时预测多个未来的 token。 这种方式 ...
python namespace 和 scope 详解我感觉很多英文名词翻译过来可能会引起误解,因为大家的背景各异,看过的书也不一样,对名词的理解也有差异,为了表述不会引起歧义,对于一些名词,文中全都用英文。name(也叫 identifier)只是 objects 的 Name。这个解释跟没有解释一样。但是在python中, 所有的东西都是一个 ob