zoukankan      html  css  js  c++  java
  • 类的继承

    1. 继承介绍

    '''
    什么是继承:
        ---是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中
        --父类/基类
        --子类/派生类
        --新式类:只要继承了object类,就是新式类,在python3中,默认继承object类
            -python3中:默认继承object
                class A:
                    pass
            -python2中,需要显示的指定继承object
        --经典类:没有继承object的类,就是经典类
            -python3中没有经典类
            -python2中才有
    
    '''
    
    class A(object):
        pass
    
    # B继承了A这个类
    class B(A):
        pass
    
    # 类的其他内置属性  __名字__
    print(B.__dict__)
    # 类名
    print(B.__name__)
    # B的父类
    print(B.__bases__)
    
    
    # 多继承
    class A(object):
        pass
    
    class C:
        pass
    # B继承了A这个类
    class B(A,C):
        pass
    
    # 类的其他内置属性  __名字__
    print(B.__dict__)
    # 类名
    print(B.__name__)
    # B的父类
    print(B.__bases__)
    
    print(C.__bases__)
    

    2. 利用继承减少代码冗余

    class Person:
        school = 'oldboy'
    
    class Teacher(Person):
    
        def __init__(self,name,age,level):
            self.name = name
            self.age = age
            self.level = level
    
    class Student(Person):
    
        def __init__(self,name,age,course):
            self.name = name
            self.age = age
            self.course = course
    
    stu1 = Student('wed',19,'python')
    print(stu1.school)
    
    # 问题一:如何重用父类的属性
    # 问题二:属性的查找顺序是什么
    #     先找对象---》类中找---》父类中找(多继承)---》报错
    # 问题三:如何重用父类的方法
    
    class Person(object):
        school = 'oldboy'
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    class Teacher(Person):
        pass
    
    class Student(Person):
        pass
    
    # 类实例化会自动调用__init__如果类中没有,去父类中找
    # stu1 = Student()   # 报错,因为父类中必须传两个参数
    stu1 = Student('nick',18)
    print(stu1.__dict__)
    
    
    # 多层继承
    class A:
        a = 'AAAA'
    class B(A):
        # a = 'BBB'
        pass
    class C(B):
        # a = 'CCC'
        pass
    class D(C):
        # a = 'DDD'
        pass
    
    d = D()
    print(d.a)
    
    
    #多继承的多层
    class A:
        # a="AAAA"
        pass
    class B:
        # a="BBB"
        pass
    
    class C:
        a="CCC"
        pass
    
    class D(A,B,C):
        # a = "DDD"
        pass
    
    d=D()
    print(d.a)
    

    3. 菱形问题

    # 继承的菱形问题:新式类和经典类的查找顺序是不一样的
    # 新式类的查找顺序:广度优先
    # 经典类的查找顺序:深度优先
    class G(object):
        a = 'GGG'
        # pass
    class F(G):
        # a = "FFF"
        pass
    class E(G):
        # a = "EEE"
        pass
    class D(G):
        # a = "DDD"
        pass
    class C(F):
        # a="CCC"
        pass
    class B(E):
        # a="BBB"
        pass
    class A(B,C,D):
        # a="AAAA"
        pass
    
    a=A()
    print(a.a)
    
    # mro列表,继承顺序查找列表(只有在新式类中有)
    print(A.mro())
    print(A.__mro__)
    
    #继承的菱形问题(显示的都继承一个类,不是object类):新式类和经典类的查找顺序是不一样的
    #新式类(py3中全是新式类):广度优先---从左侧开始,一直往上找,找到菱形的顶点结束(不包括菱形顶点),继续下一个继承的父类往上找,找到菱形的顶点结束(不包括菱形顶点),最后找到菱形顶点
    #经典类(只有py2中才有):深度优先---从左侧开始,一直往上找,找到菱形的顶点结束(包括菱形顶点)继续下一个继承的父类往上找,找到菱形的顶点结束(不包含菱形定点)
    
    #不出现菱形问题:正常查找
    

    4. 重用父类方法

    # 继承重用父类方法
    
    # object写与不写,在py3中没有区别,
    # 有的人在py3中这么写,为了向下兼容
    # 方式一:指名道姓的使用,跟继承没有关系
    class A:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    
    class Person:
        school = 'oldboy'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def study(self):
            print('study')
    
    
    class Teacher(Person):
    
        def __init__(self, name, age, level):
            A.__init__(self, name, age)
            # self.name = name
            # self.age = age
            self.level = level
    
    
    class Student(Person):
    
        def __init__(self, name, age, course):
            # 如何重用父类的__init__方法
            # 指名道姓的使用Person的__init__方法
            Person.__init__(self, name, age)
            self.course = course
    
        def study(self):
            Person.study(self)
            print(f'{self.name}在学习')
    
    
    stu1 = Student('wed', 19, 'python')
    print(stu1.school)
    stu1.study()
    
    
    # 方式二:通过super关键字,跟继承有关系
    class Person(object):
        school = 'oldboy'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def study(self):
            print('study')
    
    
    class Student(Person):
        school = 'yyyy'
    
        def __init__(self, name, age, course):
            # super()会按照mro列表拿到父类对象
            #super()相当于得到了一个特殊对象,第一个参数不需要传,调用绑定方法,会把自己传过去
            # 对象来调用绑定方法,不需要传递第一个参数(self)
            super().__init__(name, age)
            # 经典类和新式类
            # 经典类中必须这么写(py3中没有经典类),都用上面那种方式写
            #看到别人这么写:super(类名,对象)  在py3中为了兼容py2
            #在py3中这么写和省略写法完全一样
            #在py2中必须super(Student,self)写
            # super(Student,self).__init__(name,age)
            self.course = course
    
        def study(self):
            # Person.study(self)
            super().study()
    
    
    stu1 = Student('wed', 19, 'python')
    stu1.school = 'xxx'
    print(stu1.school)
    stu1.study()
    
    # 总结,有继承关系的时候,通常用super,
    # 指名道姓的方式在什么情况下用?
    # 1 没有继承关系
    # 2 如果继承了多个父类,super是按照mro列表找,现在想指名道姓的用某个父类的某个方法,就需要指名道姓的使用
    

    4.1 super练习

    #super练习
    # super是按照mro列表找
    class A:
        def f1(self):
            print('A.f1')
    class B:
        def f1(self):
            print('B.f1')
        def f2(self):
            print('B.f2')
            super().f1()
            # return 'xxxxx'
    
    class C(B,A):
    #注意这个顺序,这个顺序报错
    # class C(A,B):
        def f1(self):
            print('C.f1')
    
    #C实例化产生一个对象
    c=C()
    # print(c.f2())
    print(C.mro())
    c.f2()
    

    5. 回顾绑定方法

    class Student:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def study(self):
            print(self.name)
            print('study')
        def chang_name(obj,new_name):
            print('原来的名字是%s'%obj.name)
            obj.name=new_name
            print('修改的名字是%s' % obj.name)
    
    #类来调用对象的绑定方法(写在类中的函数,没加装饰器),有几个参数就需要传几个参数
    # Student.__init__(123,'nick',18)   # 报错
    #类实例化产生对象,会自动调用__init__完成初始化操作
    stu=Student('nick',18)
    #对象的绑定方法的特殊之处,会把对象本身当做第一个参数传入
    stu.study()
    stu2=Student('tank',18)
    stu2.study()
    
    # 修改学生姓名
    stu=Student('nick',18)
    # 方式一
    print(stu.name)
    stu.name = 'tank'
    print(stu.name)
    # 方式二
    stu.chang_name('amy')
    print(stu.name)
    # 方式三
    Student.chang_name(stu,'wed')
    print(stu.name)
    # 方式四
    # 定义一个函数
    def change_name(obj,name):
        # 修改obj对象的name属性
        print('原来的名字是%s' % obj.name)
        obj.name=name
        print('修改的名字是%s' % obj.name)
    
    change_name(stu,'bob')
    print(stu.name)
    
  • 相关阅读:
    kibana 版本kibana-4.3.1 修改地图
    安装GeoIP数据库
    获取nginx ip地理信息
    数据接口示例
    elasticsearch 搜索不支持单词的部分进行匹配
    5,扩展方案
    (?m)使用实例
    Oracle 唯一主键引发的行锁
    场景2 nginx 错误日志格式:
    POSTGRESQL NO TABLE
  • 原文地址:https://www.cnblogs.com/yushan1/p/11419125.html
Copyright © 2011-2022 走看看