继承

继承

什么是继承

​ 继承指的是新建类的方法,新建的类称之为字类或者派生类,

​ 字类继承的类叫做父类,也成为基类或者超类。

继承的特征

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

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

为什么要继承

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

如何实现继承

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

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

class 父:
	x=111
    pass
class 子(父):
    pass

继承初体验

#父类
class ParentClass1:
    pass

class ParentClass2:
    pass

#子类
class SubClass1(ParentClass1):
    pass

class SubClass2(ParentClass1,ParentClass2):
    pass

#查看继承的父类:__bases__,是类的属性,用来查找当前类的父类
print(SubClass1.__bases__)#(<class '__main__.ParentClass1'>,)
print(SubClass2.__bases__)#(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

寻找继承关系

如何寻找继承关系

​ 要想寻找继承关系,首先要"先抽象,再继承"

什么是抽象

​ 抽象指的是抽取相似的部分,称之为抽象

--先抽象(抽象思想):
奥巴马--》人类--》动物类

​ 麦兜--》猪类--》动物类

​ 小--》狗类--》动物类

​ 抽象定义动物类,称之为父类

​ 特征:

​ 眼睛,鼻子。。。

​ 技能:

​ 吃喝拉撒

--再继承(在程序中):

​ 奥巴马对象--》调用人类--》继承动物类

​ 麦兜对象--》调用猪类--》继承动物类

​ 小--》调用狗类--》继承动物类

继承的关系

​ 对象是特征与技能的结合体。

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

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

class OldboyPeople:
    school='oldboy'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

class OldboyStudent(OldboyPeople):
    def choose_course(self,course):
        print(f'学生{self.name}选择课程{course}')

class OldboyTeacher(OldboyPeople):
    def change_score(self):
        print(f'老师{self.name}修改分数')

stu1=OldboyStudent('nick',18,'male')
tea1=OldboyTeacher('tank',18,'male')
print(stu1.name,stu1.age,stu1.sex)
print(tea1.name,tea1.age,tea1.sex)
stu1.choose_course('python')
tea1.change_score()
'''
nick 18 male
tank 18 male
学生nick选择课程python
老师tank修改分数'''

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

​ 1.对象查找属性会先从对象的名称空间中查找

​ 2.若对象没有,则会去类里面找

​ 3.若当前是子类,并且没有对象找的属性,会去父类中查找

​ 注意:对象查找属性,若子列有,不管父类有没有,以子类的为准

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().f2()
'''
Foo.f2
Soo.f1'''

派生

什么是派生

​ 派生指的是子类继承父类的属性,并且派生出新的属性。*********

​ 子类派生出新的属性,若与父类的属性相同,则以子类的为准。

​ 继承是谁与谁的关系,指的是类与类的关系,子类与父类是从属关系

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

方式一

​ 直接通过父类.--init--,把--init--当作普通函数使用,传入对象与继承的属性

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 OldboyStudent(OldboyPeople):
    # 课程
    def __init__(self, name, age, sex, course):
        OldboyPeople.__init__(self, name, age, sex)
        self.course = course

    def choose_course(self):
        print(f'学生{self.name}选择课程{self.course}')

方式二

​ 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


class OldboyStudent(OldboyPeople):
    # 课程
    def __init__(self, name, age, sex, course):
        super().__init__(name, age, sex)
        self.course = course

    def choose_course(self):
        print(f'学生{self.name}选择课程{self.course}')

​ 注意:两种方法不要混用

新式类与经典类

​ 在python2中,才会有新式类与经典类之分,

​ 在python3中,所有的类都是新式类

​ 新式类:

​ 继承object的类都是新式类

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

​ 经典类:

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

mro(): 属于object--> type的函数, 用来查看当前类的继承顺序, 在多继承的情况下.
class A:
    # x = 2
    pass
class B:
    # x = 3
    pass
# 多继承情况下:
class C(A, B):
    # print('C...')
    # x = 1
    pass
print(C.mro())
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

砖石继承(菱形继承)

经典类:

​ 深度优先

新式类:

​ 广度优先

# 验证
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


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

# 经典类: F-D-B-A-E-C

通过继承实现修改json

# 开源者的角度: 修改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)

posted @ 2020-03-26 22:50  风啊风啊  阅读(297)  评论(0编辑  收藏  举报