• 继承


    继承

    1.什么是继承?

    继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类

    在python中,一个子类可以继承多个父类(面试题)

    在其他语言中,一个子类只能继承一个父类

    2.继承的作用?

    减少代码的冗余

    3.如何实现继承?

    1)先确认呢谁是子类,谁是父类

    2) 在定义类子类时,子类名(父类名)

    父类
    class Father1:
        pass
    class Father2:
        pass
    class Father3:
        pass
    子类
    class Sub(Father1,Father2,Father3):
        pass
    
    # 子类。__bases__查看父亲
    print(Sub.__bases__)
    print(Sub.x)
    

    4.如何寻找继承关系:

    确认谁是子类

    确认谁是父类

    先抽象,再继承:

    ​ 抽取对象之间相似的部分,总结出类

    ​ 抽取类之间相似的部分,总结出父类

    代码冗余
    # 老师类
    class OldboyTeacher:
    	school = 'oldboy'
        country = 'china'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        # 老师修改分数
        def change_score(self):
            print(f'老师{self.name}正在修改分数。。。')
            
    # 学生类
    class OldboyStudent:
        school = 'oldboy'
        country = 'china'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
        # 学生选择课程
        def choose_course(self):
            print(f'学生{self.name}正在选择课程。。。')
            
    解决代码冗余
    # 老男孩人类
    class OldboyPeople:
        school = 'oldboy'
        country = 'china'
        
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
            
    # 老师类
    class OldboyTeacher(OldboyPeople):
        # 老师修改分数
        def change_score(self):
            print(f'老师{self.name}正在修改分数...')
    
            
    # 学生类
    class OldboyStudent(OldboyPeople):
        # 学生选择课程
        def choose_course(self):
            print(f'学生{self.name}正在选择课程...')
            
    
        
    

    程序的执行顺序是由上而下,父类必须定义在子类的上方

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

    1.先从对象自己的名称空间中查找

    2.对象中没有,从子类的名称空间中查找

    3.子类中没有,从父类的名称空间中查找,若父类没有,则会报错

    ps: 对象中添加属性的操作
        坑:并不是修改子类的属性
    

    派生:

    ​ 指的是子类继承父类的属性与方法,并且派生出自己独有的属性和方法

    ​ 若子类中的方法名与父类的相同有先用子类的

    # 父类
    class Foo:
        def f1(self):
            print('from Foo.f1...')
    
        def f2(self):  # self ---> bar_obj
            print('from Foo.f2...')
            # bar_obj.f1() ---> 对象自己找 ---> Bar ---> Foo
            self.f1()
    
    
    # 子类
    class Bar(Foo):
    
        # 重写
        def f1(self):
            print('from Bar.f1..')
    
        def func(self):
            print('from Bar.func...')
    
    
    # bar_obj = Bar()
    # bar_obj.f1()  # from Bar.f1..
    # bar_obj.func()  # from Bar.func...
    # bar_obj.f2()  # from Foo.f2...
    
    # 派生后继承关系查找验证:
    bar_obj = Bar()
    bar_obj.f2()
    
    
    结果:
    from Foo.f2...
    from Bar.f1..
    
    

    子类继承父类,派生出自己的属性和方法,并且重用父类的属性和方法

    子类重写父类的__ init __会导致代码更加冗余

    代码冗余
    # 老师类
    class OldboyTeacher:
    	school = 'oldboy'
        country = 'china'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        # 老师修改分数
        def change_score(self):
            print(f'老师{self.name}正在修改分数。。。')
            
    # 学生类
    class OldboyStudent:
        school = 'oldboy'
        country = 'china'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
        # 学生选择课程
        def choose_course(self):
            print(f'学生{self.name}正在选择课程。。。')
    

    解决问题: 子类重用父类的属性,并派生出新的属性

    ​ 两种方式:

    ​ 1.直接引用父类的__ init __为其传参,并且添加子类的属性

    ​ 2.通过super来指向父类的属性

    ​ -super()是一个特殊的类,调用super得到一个对象,该对象指向父类的名称空间

    ​ ps: 使用哪一种都可以,但不能两种方式混合使用

    第一种
    class OldboyPeople:
        school = 'oldboy'
        country = 'china'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self, name, age, sex, sal):
            # 类调用内部的__init__只是普通的函数
            OldboyPeople.__init__(self, name, age, sex)
            self.sal = sal
    
        def change_score(self):
            print(f'老师{self.name}对成绩做了修改!')
    
    
    class OldboyStudent(OldboyPeople):
        def __init__(self, name, age, sex, hobby):
            OldboyPeople.__init__(self, name, age, sex)
            self.hobby = hobby
    
        def choose_course(self):
            print(f'学生{self.name}进行选课!')
    
    
    teacher = OldboyTeacher('tank', 28, 'female', 120000)
    print(teacher.name, teacher.sex, teacher.age, teacher.sal)
    
        
    
    第二种
    class OldboyPeople:
        school = 'oldboy'
        country = 'china'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self, name, age, sex, sal):
            # 类调用内部的__init__只是普通的函数
            super().__init__(name, age, sex)
            self.sal = sal
    
        def change_score(self):
            print(f'老师{self.name}对成绩做了修改!')
    
    
    class OldboyStudent(OldboyPeople):
        def __init__(self, name, age, sex, hobby):
            super().__init__(name, age, sex)
            self.hobby = hobby
    
        def choose_course(self):
            print(f'学生{self.name}进行选课!')
    
    
    teacher = OldboyTeacher('tank', 28, 'female', 120000)
    print(teacher.name, teacher.sex, teacher.age, teacher.sal)
    

    经典类与新式类:

    ​ 新式类:

    ​ 1.凡是继承object的类或子孙类都是新式类

    ​ 2.在python3中所有的类都默认继承object

    ​ 经典类:

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

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

    # class User(object):
    #     pass
    python3中所有的类都是继承object
    
    class User:
        x = 10
        pass
    
    
    class Sub(User):
        pass
    
    
    print(User.__dict__)
    
    
    {'__module__': '__main__', 'x': 10, '__dict__': <attribute '__dict__' of 'User' objects>, '__weakref__': <attribute '__weakref__' of 'User' objects>, '__doc__': None}
    
    
    python2中
    #!/usr/bin/u/ubv/a python
    # _*_ coding:utf8 _*_
    
    
    class User(object):
        x = 10
        pass
    
    
    class Sub(User):
        pass
    
    
    print(User.__dict__)
    
    {'__dict__': <attribute '__dict__' of 'User' objects>, 'x': 10, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'User' objects>, '__doc__': None}
    
    
    #!/usr/bin/u/ubv/a python
    # _*_ coding:utf8 _*_
    
    
    class User():
        x = 10
        pass
    
    
    class Sub(User):
        pass
    
    
    {'x': 10, '__module__': '__main__', '__doc__': None}
    
    

    调用mro返回的是一个继承序列:

    ​ super的继承顺序严格遵循mro继承序列

    多继承的情况下:从左至右

    在python3中提供了一个查找新式类查找顺序的内置方法,mro():会把当前类的继承关系列出来

    class A:
        def test(self):
            print('from A.test')
            super().test()
    
    
    class B:
        def test(self):
            print('from B.test')
    
    
    class C(A, B):
        pass
    
    print(C.mro())
    
    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    
    c = C()
    c.test()
    
    from A.test
    from B.test
    
    

    多继承情况下造成‘钻石继承’

    mro的查找顺序:

    新式类:

    ​ 广度优先

    经典类:

    ​ 深度优化

    class A(object):
        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
    print(F.mro())
    obj = F()
    obj.test()
    
    
    [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
    from F
    
    菱形继承下的经典类和新式类的详解:
    https://blog.csdn.net/XiaoMaGe1996/article/details/80828864
    
  • 相关阅读:
    48. Rotate Image
    47. Permutations II
    46. Permutations
    45. Jump Game II
    44. Wildcard Matching
    43. Multiply Strings
    42. Trapping Rain Water
    41. First Missing Positive
    40. Combination Sum II
    39. Combination Sum
  • 原文地址:https://www.cnblogs.com/godlover/p/11937791.html
Copyright © 2020-2023  润新知