类的继承、派生

面向对象的三大特征:

​ 1、继承(组合)
​ 2、封装
​ 3、多态

继承:

1、什么是继承?

​ 继承指的是新建类的方法,新建的类称之为字类或者派生类,
​ 字类继承的类叫做父类,也称之为基类或超类

继承的特征:

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

​ 注意: 在python中,一个子类可以继承多个父类,其他语言只能一个子类继承一个父类.

2、为什么要继承?

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

3、如何实现继承?

​ 1、首先要确定好谁是子类,谁是父类
​ 2、在定义时,类+(), ()内写父类名,实现继承。
​ 3、在python中,一个子类,可以继承多个父类,
​ 4、用 __ bases __ 方法可以查看对象继承的类

class ParentClass1:  # 父类
    pass

class ParentClass2:
    pass

class SubClass(ParentClass1):   # 子类:
    pass

class SubClass2(ParentClass1, ParentClass2):  # 继承多个父类
    pass

4、寻找继承关系

先抽象,再继承

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

查找顺序

在继承背景下,对象属性的查找顺序:
对象查找属性的顺序:对象的名称空间-->对象的类的名称空间-->父类的名称空间-->父类的父类-->...
用查找到的第一个属性,不再继续找,不管父类里边有没有

5、派生:

派生是指子类继承父类的属性,并派生出自己新的属性

子类派生出新的属性,若与父类的属性相同,则以子类的为准.
继承是谁与谁的关系, 指的是类与类的关系,子类与父类是从属关系.

如何在父类的基础上额外添加特征

方法一:

​ 直接通过 父类. _ init __ 调用,此时,__ init __当作普通函数使用,需要传入的参数包括对象和继承的属性。

方式二:

​ 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):
#         OldboyPeople.__init__(self, name, age, sex)  # 此处用了方式一
#         self.level = level
#         self.sal = sal

# 方式二:
class OldboyTeacher(OldboyPeople):
    # 等级, 薪资
    def __init__(self, name, age, sex, level, sal):
        super().__init__(name, age, sex)  # 此处用了方式二
        self.level = level
        self.sal = sal

6、新式类与经典类

​ 在python2中,才会有这两种区分
​ 在python3中,所有类都是新式类

新式类:

​ 继承object的类都称为新式类
​ python3中,所有没指定父类的子类都默认继承object类

经典类:

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

"""""""

在python3:
新式类:
class Foo(object):
    pass

class Goo(Foo):
    pass

# print(Foo.__bases__)  # (<class 'object'>,)
print(Goo.__bases__)  # (<class 'object'>,)

7、mro():

mro(): 属于object--> type的函数, 用来查看当前类的继承顺序, 在多继承的情况下.

class A:
    # x = 2
    pass
class B:
    # x = 3
    pass
# 多继承情况下:
class C(A, B):
    # print('C...')
    # x = 1
    pass

print(object)
print(C.mro())

打印结果:
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

8、钻石继承(菱形继承):

​ 在多层继承的情况下会形成钻石继承
​ 经典类: 深度优先
​ 新式类: 广度优先

# 验证
class A:
    # def test(self):
    #     print('from A')
    pass

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

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

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

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

class F(D,E):
    # def test(self):
    #     print('from F')
    pass

f1 = F()
f1.test()
# 新式类: F-D-B-E-C-A-object
# 经典类: F-D-B-A-E-C

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

import json
from datetime import date, datetime

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)
posted @ 2019-10-10 16:31  AllenCH  阅读(274)  评论(0编辑  收藏  举报