zoukankan      html  css  js  c++  java
  • 继承

    继承

    什么是继承

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

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

    继承的特征

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

    ​ 注意:在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)
    
    
  • 相关阅读:
    [LeetCode] 456. 132 Pattern
    [LeetCode] 606. Construct String from Binary Tree
    [LeetCode] 536. Construct Binary Tree from String
    [LeetCode] 925. Long Pressed Name
    [LeetCode] 652. Find Duplicate Subtrees
    [LeetCode] 743. Network Delay Time
    [LeetCode] 1209. Remove All Adjacent Duplicates in String II
    [LeetCode] 1047. Remove All Adjacent Duplicates In String
    [LeetCode] 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit
    [LeetCode] 859. Buddy Strings
  • 原文地址:https://www.cnblogs.com/zqfzqf/p/12578127.html
Copyright © 2011-2022 走看看