• Day 20 继承/派生/菱形继承/新式类和经典类


    类的继承

    什么是继承

    继承就是新建类的方法,新建的类被称为子类或者派生类

    子类继承的类叫做父类,也称之为基类或者超类

    继承的特征

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

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

    为什么要继承

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

    如何实现继承

    1. 首先要确定谁是子类,谁是父类
    2. 在定义类时,子类+(), ()内写父类,实现继承
    # 父类
    class ParentClass1():
        pass
    
    class ParentClass2():
        pass
    
    # 子类
    class ChildClass1(ParentClass1):
        pass
    
    # 继承多个父类
    class ChildClass2(ParentClass1, ParentClass2):
        pass
    
    # __bases__是类的属性,用来查看子类的父类
    print(ChildClass1.__bases__)
    
    print(ChildClass2.__bases__)
    
    (<class '__main__.ParentClass1'>,)
    (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
    

    继承的关系

    继承与抽象

    继承描述的是子类和父类之间的关系,是一种什么是什么的关系.要找出这种关系,必须先抽象再继承,抽象即抽取类似或者比较像的部分.

    抽象分成两个层次:

    1. 将对象间比较像的部分抽取成类
    2. 将类间比较像的部分抽取成父类

    抽象最重要的作用是划分类别

    # 选课系统
    class OldboyTeacher():
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
            
        def change_score(self):
            print('change_score')
            
    class OldboyStudent():
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
            
        def choose_course(self, course):
            print('{self.name}选择{course}课程')
    

    两个类具有相同的__init__,所以我们可以抽取出一个父类

    # 选课系统
    class OldboyPeople:
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    class OldboyTeacher(OldboyPeople):   
        def change_score(self):
            print('change_score')
            
    class OldboyStudent(OldboyPeople):   
        def choose_course(self, course):
            print('{self.name}选择{course}课程')
            
    
    stu1 = OldboyStudent('Tiny', 18, 'male')
    tea1 = OldboyTeacher('nick', 20, 'male')
    print(stu1.name, stu1.age, stu1.gender)
    print(tea1.name, tea1.age, tea1.gender)
    
    Tiny 18 male
    nick 20 male
    

    属性查找顺序

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

    对象查找属性的顺序:对象自己 ---> 对象的类 ---> 父类 ---> 父类 ---> ... ---> 报错

    类的派生

    派生:

    子类中定义新的属性(特征和技能)的过程叫做派生

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

    两种派生方式

    方式一(类调用):

    # 选课系统
    class OldboyPeople:
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self, name, age, gender, salary):
        	OldboyPeople.__init__(self, name, age, gender)
            self.salary = salary
        
        def change_score(self):
            print('change_score')
            
    class OldboyStudent(OldboyPeople):    
        def choose_course(self, course):
            print('{self.name}选择{course}课程')
            
    
    tea1 = OldboyTeacher('nick', 20, 'male', 20000)
    print(tea1.name, tea1.age, tea1.gender, tea1.salary)
    

    方式二(super):

    # 选课系统
    class OldboyPeople:
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self, name, age, gender, salary):
        	super().__init__(name, age, gender)
            self.salary = salary
        
        def change_score(self):
            print('change_score')
            
    class OldboyStudent(OldboyPeople):    
        def choose_course(self, course):
            print('{self.name}选择{course}课程')
            
    
    tea1 = OldboyTeacher('nick', 20, 'male', 20000)
    print(tea1.name, tea1.age, tea1.gender, tea1.salary)
    

    新式类和经典类

    1. 新式类
    • 继承了object的类以及该类的子类,都是新式类
    • python3中的所有类都是新式类
    1. 经典类
    • 没有继承object的类以及该类的子类,都叫做经典类
    • 只有python2中才有经典类

    菱形继承

    由于在python中允许同时继承多个父类,如A(B, C, D)

    如果继承关系为非菱形结构,则会按照先找B这条分支,然后再找C这条分支,最后找D这条分支直到找到我们需要的属性

    如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方式有两种:

    • 经典类:深度优先

    • 新式类:广度优先

    经典类:

    新式类:

    mro()方法

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,如:

    class G:
        pass
    
    class F(G):
        pass
    
    class C(F):
        pass
    
    class E(G):
        pass
    
    class B(E):
        pass
    
    class A(B, C, D):
        pass
    
    print(A.mro())
    
    class D(G):
        pass
    
    class F(G):
        pass
    
    class C(F):
        pass
    
    class E(G):
        pass
    
    class B(E):
        pass
    
    class A(B, C, D):
        pass
    
    print(A.mro())
    
    for i in A.mro():
        print(i)
    
    [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]
    
    <class '__main__.A'>
    <class '__main__.B'>
    <class '__main__.E'>
    <class '__main__.C'>
    <class '__main__.F'>
    <class '__main__.D'>
    <class '__main__.G'>
    <class 'object'>
    
  • 相关阅读:
    mysql分页查询语法
    不同浏览器CSS样式不兼容问题
    js引入jquery问题
    ElasticSearcher的安装以及安装过程中出现的问题
    Mybites逆向工程的搭建
    Maven遇到的各种问题
    Maven安装和配置
    Maven报错:Unsupported major.minor version 51.0
    teamviewer远程是账号密码都没错但是报正在初始化参数...
    远程服务器时无密码登录
  • 原文地址:https://www.cnblogs.com/2222bai/p/11650195.html
Copyright © 2020-2023  润新知