python-面向对象.继承

继承

1.单继承

父类也叫基类

子类也叫派生类

如下所示,继承的关系:

 

继承的书写格式:

class 子类(父类):

        方法

实例:

class Animal:

         def eat(self):

                print("-----吃-------")

        def drink(self):

                print("-----喝--------")

class Dog(Animal):

        def drak(self):

                print("汪汪叫")

a=Animal()

a.eat()

b= Dog()

b.eat()

孙类是可以继承爷爷类的,如下所示:

class Animal:

        def eat(self):

                print("---吃-----")

         def drink(self):

                print("----喝-----")

        def sleep(self):

                 print("----睡觉-----")

class Dog(Animal):

        def bark(self):

                 print("---汪汪叫----")

class Xiaotq(Dog):

        def fly(self):

                print("----飞-----")

xiaotq = Xiaotq()

xiaotq.fly()

xiaotq.bark()

xiaotq.eat()

2.重写

子类和父类中拥有方法名相同的方法,说明子类重写了父类的方法 重写的作用:父类中已经有了这个方法,但子类想修改里面的内容,直接 修改父类是不好的,就需要用到重写

例如:

class Animal:

        def eat(self):

                 print("---吃-----")

        def drink(self):

                 print("----喝-----")

        def sleep(self):

                print("----睡觉-----")

class Dog(Animal):

         def bark(self):

                print("---汪汪叫----")

class Xiaotq(Dog):

        def fly(self):

                print("----飞-----")

        def bark(self):

                print("----狂叫-----")

xiaotq = Xiaotq()

xiaotq.fly()

xiaotq.bark()

xiaotq.eat()

这样做,父类的方法是不会被调用的,需要用以下方式:

class Animal:

        def eat(self):

                 print("---吃-----")

        def drink(self):

                print("----喝-----")

        def sleep(self):

                print("----睡觉-----")

class Dog(Animal):

        def bark(self):

                print("---汪汪叫----")

class Xiaotq(Dog):

        def fly(self):

                print("----飞-----")

        def bark(self):

                print("----狂叫-----")

                #调用被重写的父类的方法

                #1 必须加上self

                Dog.bark(self)

                #2

                super().bark()

xiaotq = Xiaotq()

xiaotq.fly()

xiaotq.bark()

xiaotq.eat()

3、多继承

就是一个子类继承多个父类:

 

多 继 承 的 例 子 , 如 下 :

# -*- coding:utf-8 -*-
'''
@Author: 董咚咚
@contact: 2648633809@qq.com
@Time: 2023/7/31 17:02
@version: 1.0
'''
class Base(object):
    def test(self):
        print("-----base")
        
class A(Base):
    def test1(self):
        print("-----test1")
        
class B(Base):
    def test2(self):
        print("-----test2")
        
class C(A,B):
    pass

c = C
c.test1()
c.test2()
c.test()

 

 C也能继承Base

        注:多继承中,每个父类都有相同的方法,子类继承时,会有一个继承顺 序

         想要查看该顺序的调用流程可以使用以下方法:

        print(子类类名.__mro__)

        最后调用的是object方法,如果object方法也不存在,说明类中没有这个方 法

class Base(object):

         def test(self):

                print("-----Base")

class A(Base):

         def test(self):

                print("----A")

class B(Base):

        def test(self):

                print("----B")

class C(A,B):

        def test(self):

                print("-----C")

c=C()

c.test()

方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的 方法,

实例如下:

class Parent        : # 定义父类

        def myMethod(self):

                 print ('调用父类方法')

class Child(Parent):         # 定义子类

        def myMethod(self):

                print ('调用子类方法')

c = Child()         # 子类实例

c.myMethod() # 子类调用重写方法

super(Child,c).myMethod()         #用子类对象调用父类已被覆盖的方法

                                                        # super() 函数是用于调用父类(超类)的一 个方法。

        对于”super(Child, self).foo()”可以理解为, 首先找到Child的父类Parent,然后调用父类的foo方法, 同时将Child的实例self传递给foo方法。

当心掉进Python多重继承里的坑

不惜一切代价地避免多重继承,它带来的麻烦比能解决的问题都多。如果 你非要用,那你得准备好专研类的层次结构,以及花时间去找各种东西的 来龙去脉吧

只有在代码之间有清楚的关联,可以通过一个单独的共性联系起来的时候 使用继承,或者你受现有代码所限非用不可的话,那也用吧 或者可以试试组合,组合则是利用模块和别的类中的函数调用实现了相同的 目的

一个例子,我们有一个基类,该基类有一个call_me方法,有两个子类重写 了这个方法,然后第3个类通过多重继承扩展了两个方法。这称为钻石继 承。

从技术上来说,在python3的所有多重继承都是钻石继承,因为所有的类都 从object继承,

 上图中的object.__init__同样是一个钻石问题。

把上图转化成代码如下:

class BaseClass:

        num_base_calls = 0

        def call_me(self):

                print("Calling method on Base Class")

                 self.num_base_calls += 1

class LeftSubclass(BaseClass):

         num_left_calls = 0

         def call_me(self):

                BaseClass.call_me(self)

                print("Calling method on Lef Subclass")

                self.num_left_calls += 1

class RightSubclass(BaseClass):

        num_right_calls = 0

         def call_me(self):

                BaseClass.call_me(self)

                print("Calling method on Right Subclass")

                self.num_right_calls += 1

class Subclass(LeftSubclass, RightSubclass):

        num_sub_calls = 0

        def call_me(self):

                 LeftSubclass.call_me(self)

                RightSubclass.call_me(self)

                print("Calling method on Subcalss")

                 self.num_sub_calls += 1

s = Subclass()

s.call_me()

print(s.num_sub_calls, s.num_left_calls, s.num_right_calls, s.num_base_calls)

调用并得到如下输出:

Calling method on Base Class

Calling method on Lef Subclass

Calling method on Base Class

Calling method on Right Subclass

Calling method on Subcalss

1 1 1 2

基类的call_me被调用了两次。但这不是我们想要的,如果在做实际的工 作,

这将导致非常严重的bug,如银行存款存了两次。

对于多重继承,我们只想调用“下一个”方法,而不是父类的方法。

实际上, 下一个方法可能不属于当前类或者当前类的父类或者祖先类。

关键字super可以解决这个问题,

如下是代码重写:

class BaseClass:

        num_base_calls = 0

        def call_me(self):

                print("Calling method on

                Base Class")

                self.num_base_calls += 1

class LeftSubclass(BaseClass):

        num_left_calls = 0

        def call_me(self):

                super().call_me()

                print("Calling method on Lef Subclass")

                 self.num_left_calls += 1

class RightSubclass(BaseClass):

        num_right_calls = 0

        def call_me(self):

                super().call_me()

                 print("Calling method on Right Subclass")

                self.num_right_calls += 1

class Subclass(LeftSubclass, RightSubclass):

        num_sub_calls = 0

         def call_me(self):

                super().call_me()

                print("Calling method on Subcalss")

                self.num_sub_calls += 1

s = Subclass()

s.call_me()

print(s.num_sub_calls, s.num_left_calls, s.num_right_calls, s.num_base_calls)

执行结果如下:

Calling method on Base Class

Calling method on Right Subclass

Calling method on Lef Subclass

Calling method on Subcalss

1 1 1 1

        首先,Subclass的call_me方法调用了super().call_me(),其实就是引用了LeftSubclass.call_me()方法。然后LeftSubclass.call_me()调用了super().call_me(),

但是这时super()引用了RightSubclass.call_me()。 需要特别注意:super调用并不是调用LeftSubclass的超类(就是BaseClass)的方法。

它是调用RightSubclass,虽然它不是LeftSubclass的父类!这就是下一个方 法, 而不是父类方法。RightSubclass然后调用BaseClass,并且通过super调用保 证在类的 层次结构中每一个方法都被执行一次。

 

看图分析:

1、CClass类的work()方法调用了super.work,其实是引用了AClass.work()

2、在AClass.work()中,调用了super.work(),这时候是引用了BClass.work(),而不是BaseClass.work(),这就是所谓的下一个方法

3、接着在BClass.work()中调用了super.work()方法,

这时候才是去调用BaseClass.work()方法

super的牛逼之处

1、在类的继承层次结构中,只想调用"下一个方法",而不是 父类的方法

2、super的目标就是解决复杂的多重继承问题(基类被调用 两次的问题)

3、super是绝对的保证,在类的继承层次结构中每一个方法 只被执行一次

经典类和新式类

所有直接继承或者间接继承object的类,都是新式类,object称之为根类, 意思时所有类都是源自object类

• 为什么这么设计? 创建对象时,需要申请内存空间,创建新的名称空间,将对象的属性放入 名称空间,

这一复杂的基础操作都是由object完成的。简单来说就是object提供了一些 常用的基础操作

注意:

1.在python3中,所有类都是object的子类,所有类都是新式类

2.在python2中,默认的是经典类,不会继承object

#区别

#python3中定义类

class Cls():

        print('python3中定义类')

#python2中

class Cls(Object):

        print('python2中定义类')

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【100天精通python】Day21:文件及目录操作_文件的权限处理和批量处理

目录 专栏导读 1. 文件的权限处理 1.1 查询文件权限 1.2 修改文件权限 2 文件的批量处理 2.1 使用os模块和os.listdir()函数 2.2 使用glob模块 2.3 使用shutil模块 2.3.1 批量复制文件 2.3.2 批量移动文件 2.3.3 批量删除文件 2.3.4 批量创建目录 专栏导读 专栏订阅…

聊聊拉长LLaMA的一些经验

Sequence Length是指LLM能够处理的文本的最大长度,越长,自然越有优势: 更强的记忆性。更多轮的历史对话被拼接到对话中,减少出现遗忘现象 长文本场景下体验更佳。比如文档问答、小说续写等 当今开源LLM中的当红炸子鸡——LLaMA…

[Docker实现测试部署CI/CD----相关服务器的安装配置(1)]

目录 0、CI/CD系统最终架构图规划IP地址 1、git配置Git下载pycharm配置gitidea配置git 2、GitLab安装与配置主机要求拉取镜像定义 compose.yml启动gitlab浏览器访问并修改密码查看登录密码修改密码 3、SonarQube 安装与配置拉取镜像修改虚拟内存的大小启动SonarQube登录 SonarQ…

2023 蓝桥杯真题B组 C/C++

https://www.dotcpp.com/oj/train/1089/ 题目 3150: 蓝桥杯2023年第十四届省赛真题-冶炼金属 题目描述 小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。这个炉子有一个称作转换率的属性 V,V 是一个正整数,这意味着消耗 V 个普通金 属 O…

价值 1k 嵌入式面试题-计算机网络 OSI

开门见山 请讲下 OSI 各层协议的主要功能? 常见问题 回答不系统回答不确切无法和实际网络协议做关联对应 答题思路 OSI 代表了开放互联系统中信息从一台计算机的一个软件应用流到另一个计算机的另一个软件应用的参考模型 OSI 包含 7 层,每一层负责特…

51单片机学习--串口通信

首先需要配置寄存器: 下面这里SCON配0x40和0x50都可以,因为暂时还不需要接受信息,所以REN置1置0都可 void Uart_Init(void) //4800bps11.0592MHz {PCON | 0x80; //使能波特率倍速位SMODSCON 0x50; //8位数据,可变波特率TMOD & 0x0F…

tinkerCAD案例:29. 摇头娃娃

Research Your Favorite Bobblehead 摇头娃娃 Project Overview: 项目概况: Design and create your favorite Minecraft 3D bobble head. All you need is a computer, 3D printer, spring and your creativity to your favorite Minecraft character in the for…

1、Hadoop3.x 从入门到放弃,第一章:概念

Hadoop3.x从入门到放弃,第一章:概念 一、什么是大数据 1、主要解决什么 大数据主要解决:海量数据的“采集”、“存储” 和 "分析计算" 问题2、大数据特点 1> Volume 大量 2> velocity 高速 3> variety 多样性数据分为…

网络层:IP协议/Mac协议

IP协议 主机: 配有IP地址, 但是不进行路由控制的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统 称; IP 目标网络(前半部分) 目标主机(后半部分) IP层的核心:IP地址定位主机(定…

Socks IP轮换:为什么是数据挖掘和Web爬取的最佳选择?

在数据挖掘和Web爬取的过程中,IP轮换是一个非常重要的概念。数据挖掘和Web爬取需要从多个网站或来源获取数据,而这些网站通常会对来自同一IP地址的请求进行限制或封锁。为了避免这些问题,数据挖掘和Web爬取过程中需要使用Socks IP轮换技术。在…

《向量数据库指南》——如何持久化存储 LlamaIndex 向量索引?

随着 AGI 时代的到来,越来越多的开发者开始思考如何有效利用大模型,不过,大家在构建 LLM 应用时普遍会面临三大挑战: LLM 的使用成本高昂LLM 无法及时提供最新信息LLM 缺乏特定专业领域的知识 针对上述问题,业界主流的做法是采用两种主要框架:微调和缓存 + 注入。 …

集团MySQL的酒店管理系统

酒店管理系统 概述 基于Spring Spring MVC MyBatis的酒店管理系统,主要实现酒店客房的预定、入住以及结账等功能。使用Maven进行包管理。 用户端主要功能包括: 登录注册、客房预订、客房评论(编写评论和查看评论) 后台管理主要…

如何在 Ubuntu 22.04 下编译 StoneDB for MySQL 8.0 | StoneDB 使用教程 #1

作者:双飞(花名:小鱼) 杭州电子科技大学在读硕士 StoneDB 内核研发实习生 ❝ 大家好,我是 StoneDB 的实习生小鱼,目前正在做 StoneDB 8.0 内核升级相关的一些事情。刚开始接触数据库开发没多久&#xff0c…

Linux 学习记录59(ARM篇)

Linux 学习记录59(ARM篇) 本文目录 Linux 学习记录59(ARM篇)一、IIC总线1. 概念2. IIC总线硬件连接 二、系统框图三、IIC时序1. 起始信号 / 停止信号2. 数据传输信号3. 应答信号 / 非应答信号4. 寻址信号 四、IIC协议1. 主机给从机发送一个字节(写)2. 主机给从机发送多个连续字…

MySQL 的 Join 查询及 Hash Join 优化 | StoneDB 技术分享会 #3

StoneDB开源地址 https://github.com/stoneatom/stonedb 设计:小艾 审核:丁奇、宇亭 编辑:宇亭 作者一:徐鑫强(花名:无花果) 电子科技大学-计算机技术-在读硕士、StoneDB 内核研发实习生 作…

Android 卡顿分析与布局优化

一、什么是卡顿?或者说我们怎么感知APP卡顿? 这里面涉及到android UI渲染机制,我们先了解一下android UI是怎么渲染的,android的View到底是如何一步一步显示到屏幕上的? android系统渲染页面流程: 1&…

重新审视MHA与Transformer

本文将基于PyTorch源码重新审视MultiheadAttention与Transformer。事实上,早在一年前博主就已经分别介绍了两者:各种注意力机制的PyTorch实现、从零开始手写一个Transformer,但当时的实现大部分是基于d2l教程的,这次将基于PyTorch…

使用javax.validation.constraints进行数据验证

使用javax.validation.constraints进行数据验证 在Java应用中,数据的验证是一个很重要的部分,特别是在接收用户输入或处理外部数据时。为了简化和标准化数据验证的过程,Java提供了javax.validation.constraints包,其中包含一系列注…

乳腺癌CT影像数据的深度学习:R语言与ANN神经网络构建高性能分类诊断模型

一、引言 乳腺癌是全球最常见的女性恶性肿瘤之一,也影响着男性的健康。据统计,每年有数百万人被诊断出患有乳腺癌[1]。乳腺癌的早期检测和准确诊断对于治疗和预后至关重要。然而,乳腺癌的早期诊断面临许多挑战,如图像解读的主观性…

uniapp 微信小程序:v-model双向绑定问题(自定义 props 名无效)

uniapp 微信小程序:v-model双向绑定问题(自定义 props 名无效) 前言问题双向绑定示例使用 v-model使用 v-bind v-on使用 sync 修饰符 参考资料 前言 VUE中父子组件传递数据的基本套路: 父传子 props子传父 this.$emit(事件名, …