前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >继承、派生、新式类与经典类

继承、派生、新式类与经典类

作者头像
GH
发布2019-12-12 16:57:53
5680
发布2019-12-12 16:57:53
举报
文章被收录于专栏:python、mysql、go知识点积累

继承

Downwards is the only way forwards .——《盗梦空间》

面向对象阶段最重要的知识点:继承、封装、多态

1.什么是继承?

指新建类的方法,新建的类称之为子类或者派生类,子类继承的类叫做父类,也称之为基类或者超类。 继承特征: 子类可以继承父类的属性(特征与技能),并且可以派生出自己的属性(特征与技能)。 在python中一个子类可以继承多个父类,其他语言一个子类只可以继承一个父类

2.为什么要继承?

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

3.如何实现继承?

1.首先要确定好谁是子类谁是父类. 2.在定义类时子类+(),()内写父类,实现继承.

代码语言:javascript
复制
class 父类:
     pass

class 子类(父类):
     pass
#父类
class ParentClass1:
    pass

class ParentClass2:
    pass
#子类
class Subclass1(ParentClass1):
    pass

class Subclass2(ParentClass1,ParentClass2):
    pass

print(Subclass2.__bases__)
#(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
#查看继承的父类:__bases__,是类的属性,用来查找自己的父类,通过元组的形式返回所继承的父类

寻找继承关系

如何寻找继承关系? 要想寻找继承关系,首先抽象再继承。 ——先抽象(抽象思想):

奥巴马——》人类——》动物类 麦兜——》猪类——》动物类 小丁丁——》狗类——》动物类 抽象定义动物类,父类。 特征:眼睛、鼻子... 技能: 吃喝...

——再继承(在程序中)

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

代码语言:javascript
复制
class SchoolPeople:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class Students(SchoolPeople):
    def choose_course(self):
        print(f'{self.name} is choosing course.')

class Teachers(SchoolPeople):
    def teach(self):
        print(f'{self.name} is teaching students.')

stu1 = Students('xiaoming','15','男')
stu1.choose_course()

xiaoming is choosing course.

继承背景下对象属性的查找顺序

对象查找属性先从自己的名称空间查找,若当前类是子类,并且没有该属性,就去父类中查找,如果父类也没有就报错__class__查看当前对象的类。 注意:对象查找属性不管父类有没有这个属性,只要子类有就不会去父类中查找

查看对象名称空间 print(tea1.__dict__) 查看对象的属性,查看当前对象的类__class__

查看子类名称空间 print(tea1.__class__.__dict__) 查看父类名称空间 print(tea1.__class__.__bases__[0].__dict__)#查看第一个父类的名称空间

代码语言:javascript
复制
#验证对象属性的查找顺序
class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.f1()

class Soo(Foo):
    def f1(self):
        print('Soo.f1')

soo_obj = Soo()
soo_obj.f2()
'''
Foo.f2
Soo.f1
'''

派生

什么是派生?

派生指子类继承父类的属性,并且派生自己的属性。 如果子类和父类都有这个属性,以子类自己的属性为准。 继承指的是类与类的关系,子类与父类是从属关系。

子类派生出新的属性,并重用父类的属性

代码语言:javascript
复制
class SchoolPeople:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class Teacher(SchoolPeople):
    def __init__(self,name,age,gender,level,sal):
        SchoolPeople.__init__(self,name,age,gender)#重用父类的属性
        self.level = level#派生出的属性
        self.sal = sal#派生出的属性

tech1 = Teacher('xiaohua','17','男','10','5w')
print(tech1.level)
重用父类属性的两种方式

方式一:

直接通过父类.(调用)__init__,把__init__当做普通函数使用,传入对象与继承的属性,如上例中的重用。 方式二:

super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,通过“.” 指向父类的名称空间。

代码语言:javascript
复制
class SchoolPeople:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

class Teacher(SchoolPeople):
    def __init__(self,name,age,gender,level,sal):
        super().__init__(name,age,gender)#重用父类的属性(注意括号里面没有self)
        self.level = level#派生出的属性
        self.sal = sal#派生出的属性

注意:两种方式不要混着使用

新式类与经典类

新式类与经典类(了解)(面试会问)

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

python3中都是新式类,继承object类的都是新式类,py3中默认继承object类。

钻石继承(菱形继承)

关于mro()

mro():是object——》type的函数,用来查看多继承情况下,当前类的继承顺序, .mro()方法其实就是在查找mro()方法 一个子类如果继承多个父类,属性的查找顺序是从左向右依次查找,最后找object

钻石继承

钻石继承(菱形继承):钻石继承就是一个子类有多个父类,每个父类又有多个不同的父类......这些父类的祖先最终是同一个祖宗。(面试问)

在多继承情况下可能会出现钻石继承的情况。

钻石继承下对象属性的查找顺序

--经典类——》深度优先:从左向右查找,一条分支找到底,若果没找到就去另一条分支继续找。

——新式类——》广度优先:从左向右查找,和经典类的区别是最后找所有分支共同的父类

验证查找顺序代码

代码语言:javascript
复制
class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

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

通过继承实现为json增加数据类型:

代码语言:javascript
复制
import json
from datetime import date ,datetime
print(json.JSONDecoder)#<class 'json.decoder.JSONDecoder'>
print(datetime.today())#当前时间
print(date.today())#当前日期
#从开发者的角度考虑,可以将json不支持的数据类型转成json支持的是数据类型
#如:
'''dict1 = {
    'name':'tank',
    'today':str(datetime.today()),
    'today1':str(date.today())
}
res = json.dumps(dict1)
print(res)
#{"name": "tank", "today": "2019-10-10 14:30:26.967368", "today1": "2019-10-10"}
从开源者的角度考虑,Python time strftime() 函数接收以时间元组,并返回以可读字符串表示的当地时间,
        格式由参数format决定。'''
class MyJson(json.JSONEncoder):
    def default(self,o):
        if isinstance(o,datetime):#判断o是否是datetime的一个实例对象
            return o.strftime('%Y-%m-%d %X')

        elif isinstance(o,date):
            return o.strftime('%Y-%m-%d')
        else:
            return super().default(self,o)#在json中也有default这个方法

dict1 = {
    'name':'tank',
    'today':datetime.today(),
    'today1':date.today()
}
res = json.dumps(dict1,cls = MyJson)#cls=None,默认指向的是原json的JSONEncoder,加上之后优先使用外面的类
print(res)

总结

1.什么是继承? 继承指的是新建类的方法, 新建的类称之为子类或者派生类,子类继承的类叫做父类,也称之为基类或超类.

代码语言:javascript
复制
继承的特征:
    子类可以继承父类的属性(特征与技能), 并且可以派生出自己的属性(特征与技能).

2.继承的目的: 继承的目的是为了减少代码冗余(减少重复代码).

3.什么是抽象? 抽象指的是抽取相似的部分,称之为抽象.

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

5.在继承背景下,对象属性的查找顺序: 1.对象查找属性会先从对象的名称空间中查找. 2.若对象没有,则会去类里面找. 3.若当前类是子类,并且没有对象找的属性,会去父类中查找

6.什么是派生? 派生指的是子类继承父类的属性,并且派生出新的属性.(*****) 子类派生出新的属性,若与父类的属性相同,则以子类的为准. 继承是谁与谁的关系, 指的是类与类的关系,子类与父类是从属关系.

7.子类派生出新的属性,并重用父类的属性: - 直接通过 父类.(调用)init,把__init__当做普通函数使用,传入对象与继承的属性. - super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,

8.什么经典类与新式类: 继承object的类都称之为新式类. 在python2中,凡是没有继承object的类都是经典类.

9.在多继承的情况下形成的钻石继承 (继承顺序) - 经典类: 深度优先 - 新式类: 广度优先

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-10-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 继承
    • 1.什么是继承?
      • 2.为什么要继承?
        • 3.如何实现继承?
          • 寻找继承关系
            • 继承背景下对象属性的查找顺序
            • 派生
              • 什么是派生?
                • 子类派生出新的属性,并重用父类的属性
                  • 重用父类属性的两种方式
              • 新式类与经典类
                • 钻石继承(菱形继承)
                  • 关于mro()
                  • 钻石继承
                  • 钻石继承下对象属性的查找顺序
                • 通过继承实现修改json模块数据类型
                • 总结
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档