继承和派生

1|01. 继承

1|11. 什么是继承

  • 继承:就是新建类的方法,新建的类称之为子类或者派生类,子类继承的类叫做父类,也称之为基类或超类。简单的说:一个类可以得到另一个类名称空间中的属性和方法的这个特性,这种特性就是通过继承来实现的

  • 继承的特征:

    子类可以继承父类的属性(特征和技能),并且可以派生出自己的属性(特征和技能)

  • 在python中,一个子类可以继承多个父类,其它编程语言只能一个子类继承一个父类(面试可能会问)

1|22. 为什么要继承

  • 继承的目的就是为了减少代码冗余(减少重复代码)

1|33. 怎么继承,如何实现继承

  1. 首先要确定好谁是子类谁是父类

  2. 在定义类时,子类 + () ,()内写父类的名字,实现子类继承父类

    # 子类B继承父类A class A: pass class B(A): pass print(B.__bases__) #查看B继承的父类们,以元组飞形式打印出各父类 print(B.__bases__[0].__dict__) # 查看B的第一个父类的属性
  3. 什么是抽象?
    抽象指的是抽取相似的部分,称之为抽象.

  4. 继承的关系:
    对象是特征与技能的结合体.
    类是一系列对象相同的特征与技能的结合体.
    继承是一系列类相同的特征与技能的结合体.

1|44. 继承后,对象的属性的搜索顺序

  • 下面的查找中,只要找到了就不会继续找了
  1. 先从对象的名称空间中查找该属性
  2. 若对象的名称空间中没有,就会去子类的名称空间中查找
  3. 若子类中没有,就去父类中查找,并且按照父类的继承顺序查找。

1|55. 新式类和经典类(面试会问)

  • python2 中才会有新式类和经典类之分。
  • python3 中所有的类都是新式类

1|01. 新式类

  • 什么是新式类:

    继承object的类都称之为新式类

    python3 中,子类如果不继承自定义的类,会默认继承object

1|02. 经典类

  • 什么是经典类

    在python2 中,凡是没有继承object 的类都是经典类

1|03. mro() / __class__ / __name__ 方法

  • mro()方法是属于object类中的方法,在多继承情况下,可以用来查看当前类的继承顺序。他返回的结果是一个元组。注意要索引取值。
  • __class__ 是对象的方法,可以获得实例化该对象的类。
  • __name__ 一种通用的方法,类/函数 通过.__name__可以获取类/函数的 名字。

1|04. 钻石继承(也称为菱形继承)

  • 在多继承的情况下会形成钻石继承

  • 钻石继承的继承顺序:分为 新式类 和 经典类 的继承顺序

1|0(1) 新式类的钻石继承顺序

  • 新式类的钻石继承顺序为 : 广度优先。

  • 它的特点是按一个子类的继承时括号内的书写顺序,从左到右依次,(如子类1(A,D,G...)),先继承:

    第一个父类A——》A的父类B——》B的父类C——》。。。

    第二个父类D——》D的父类E——》E的父类F——》。。。

    。。。

    但最后继承顶层的父类,再继承object类

1|0(2) 经典类的钻石继承顺序

  • 经典类的钻石继承顺序为: 深度优先

  • 它的特点是按一个子类的继承时括号内的书写顺序,从左到右依次,(如子类1(A,D,G...)),先继承:

    第一个父类A——》A的父类B——》B的父类C——》。。。——》顶层的父类

    第二个父类D——》D的父类E——》E的父类F——》。。。——》顶层父类继承过了,到顶层的父类的最近的一个儿子类就结束继承。开始第三个父类,第三个父类也是同第二个父类一样的继承顺序。

    。。。

2|02. 继承的实例

  • 通过继承实现修改json模块的数据类型

    import json from datetime import date, datetime print(json.JSONEncoder) print(datetime.today()) # 当前时间 print(date.today()) # 当前日期 # 开发者的角度: 直接转成str # dict1 = { # 'name': 'tank', # 'today': str(datetime.today()), # 'today2': str(date.today()) # } # # res = json.dumps(dict1) # print(res) # isinstance: # python内置的函数,可以传两个参数,判断参数一是否式参数二的一个实例. *********************继承的使用*********************** # 开源者的角度: 修改json源码 class MyJson(json.JSONEncoder): def default(self, o): # 子类派生的功能 # 判断o是否式datetime的一个实例 if isinstance(o, datetime): return o.strftime('%Y-%m-%d %X') elif isinstance(o, date): return o.strftime('%Y-%m-%d') else: # 继承父类的default方法的功能 return super().default(self, o) dict1 = { 'name': 'tank', 'today': datetime.today(), 'today2': date.today() } res = json.dumps(dict1, cls=MyJson) # cls=None,默认指向的是原json的JSONEncoder print(res)

3|03. 派生

3|11. 什么是派生

  • 派生指的是子类继承父类的属性,并且产生自己新的属性
  • 子类派生出新的属性,若与父类的属性相同,则以子类的为准。

3|22. 子类派生出新的属性,并重用父类的属性

问题:子类继承了父类的__init__属性,但还需要添加自己的一些新的属性

解决方法:

注意下面的两种方法不要混合使用

  • 方法一:

    直接通过 父类.__init__(self,要重用的属性) 来实现重用父类属性 class OldboyPeople: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyTeacher(OldboyPeople): # 等级, 薪资 def __init__(self, name, age, sex, level, sal): OldboyPeople.__init__(self, name, age, sex) self.level = level self.sal = sal
  • 方法二:(比方法一,少写了self)

    super是一个特殊的类,在子类中调用super()会得到一个特殊的对象, 通过"."指向的是父类的名称空间. class OldboyPeople: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class OldboyTeacher(OldboyPeople): # 等级, 薪资 def __init__(self, name, age, sex, level, sal): super().__init__(name, age, sex) self.level = level self.sal = sal

__EOF__

本文作者BigSun丶
本文链接https://www.cnblogs.com/Mcoming/p/11648315.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   BigSun丶  阅读(316)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示