zoukankan      html  css  js  c++  java
  • 面向对象之继承

     

    一、继承

    1、什么是继承?

      继承是一种新建类的方式,在python中支持一个儿子继承多个爹

      新建的类称为子类或派生类

      父类又可以称为基类或超类

      子类会‘’遗传‘’父类的属性

    2、为什么要继承?

      减少代码冗余

    3、怎么用继承?

    class ParentClass1:
        pass
    
    class ParentClass2:
        pass
    
    class Subclass1(ParentClass1):
        pass
    
    class Subclass2(ParentClass1,ParentClass2):
        pass
    
    print(Subclass1.__bases__)#(<class '__main__.ParentClass1'>,)
    print(Subclass2.__bases__)#(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

    在python2中有经典类与新式类之分

    在python3中全部为新式类

    二、寻找继承关系

    1、继承是类与类之间的关系,寻找这种关系需要先抽象再继承

    class OldboyPeople:
        school='oldboy'
    
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
    class OldboyTeacher(OldboyPeople):
        def change_score(self):
            print('teacher %s is changing score'%self.name)
    
    
    
    class OldboyStudent(OldboyPeople):
        def choose(self):
            print('student %s choose course'%self.name)
    
    tea1=OldboyTeacher('egon',18,'male')#OldboyTeacher.__init__(...)
    stu1=OldboyStudent('alex',73,'female')
    print(tea1.name)#egon
    print(stu1.name)#alex

    三、基于继承属性的查找

    class OldboyPeople:
        school='oldboy'
    
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def f1(self):
            print('爹的f1')
    
    class OldboyTeacher(OldboyPeople):
        def change_score(self):
            print('teacher %s is changing score'%self.name)
    
    tea1=OldboyTeacher('egon',18,'male')
    print(tea1.__dict__)#{'name': 'egon', 'age': 18, 'sex': 'male'}
    print(tea1.name)#egon
    print(tea1.school)#oldboy
    print(tea1.change_score)
    #<bound method OldboyTeacher.change_score of <__main__.OldboyTeacher object at 0x00000236244C7A58>>
    print(tea1.f1)
    #<bound method OldboyPeople.f1 of <__main__.OldboyTeacher object at 0x00000271923D7A58>>
    
    
    
    class Foo:
        def f1(self):
            print('Foo.f1')
    
        def f2(self):#self=obj
            print('Foo.f2')
            self.f1()#obj.f1()
    
    class Bar(Foo):
        def f1(self):
            print('Bar.f1')
    
    obj=Bar()
    # print(obj.__dict__)
    obj.f2()#Foo.f2,Bar.f1

    四、派生

    什么是派生?

      子类定义自己新的属性,如果与父类同名,以子类自己的为准

    class OldboyPeople:
        school='oldboy'
    
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def f1(self):
            print('爹的f1')
    
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            self.name=name
            self.age=age
            self.sex=sex
    
            self.level=level
            self.salary=salary
    
        def change_score(self):
            print('teacher %s is changing score'%self.name)
    
        def f1(self):
            print('儿子的f1')
    
    
    tea1=OldboyTeacher('egon',18,'male',9,3.1)
    tea1.f1()#儿子的f1
    print(tea1.name,tea1.age,tea1.sex,tea1.level,tea1.salary)#egon 18 male 9 3.1

    五、重用父类

      在子类派生出的新方法中重用父类

    方式一:指名道姓的调用(其实与继承是没有关系的)

    class OldboyPeople:
        school='oldboy'
    
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def tell_info(self):
            print('''
            -----------个人信息-----------
            姓名:%s
            年龄:%s
            性别: %s
            '''%(self.name,self.age,self.sex))
    
    
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            
            OldboyPeople.__init__(self,name,age,sex)
            
            self.level=level
            self.salary=salary
    
        def tell_info(self):
            
            OldboyPeople.tell_info(self)
            
            print('''
            等级:%s
            薪资:%s
            '''%(self.level,self.salary))
    
    tea1=OldboyTeacher('egon',18,'male',9,3.1)
    # print(tea1.name,tea1.age,tea1.sex,tea1.level,tea1.salary)#egon 18 male 9 3.1
    tea1.tell_info()
    '''
            -----------个人信息-----------
            姓名:egon
            年龄:18
            性别: male
            
    
            等级:9
            薪资:3.1
    '''

    方式二:super()调用(严格依赖于继承)

    super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性

    在python2中,super(自己的类名,self)

    class OldboyPeople:
        school='oldboy'
    
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def tell_info(self):
            print('''
            -----------个人信息-----------
            姓名:%s
            年龄:%s
            性别: %s
            '''%(self.name,self.age,self.sex))
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            # OldboyPeople.__init__(self,name,age,sex)
            super().__init__(name,age,sex)
    
            self.level=level
            self.salary=salary
    
        def tell_info(self):
            # OldboyPeople.tell_info(self)
            super().tell_info()
            print('''
            等级:%s
            薪资:%s
            '''%(self.level,self.salary))
    
    tea1=OldboyTeacher('egon',18,'male',9,3.1)
    # print(tea1.name,tea1.age,tea1.sex,tea1.level,tea1.salary)#egon 18 male 9 3.1
    tea1.tell_info()
    '''
            -----------个人信息-----------
            姓名:egon
            年龄:18
            性别: male
            
    
            等级:9
            薪资:3.1
    '''

    六、经典类与新式类

    1、新式类(广度优先):

      继承object的类,以及该类的子类都是新式类

      在python3中,如果一个类没有指定的父类,默认就是继承object

      所以在python3中所有的类都是新式类

    2、经典类(深度优先,只有python2中才区分经典类与新式类):

      没有继承object的类,以及该类的子类都是经典类

    #新式类&经典类
    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    print(Foo.__bases__)#(<class 'object'>,)
    print(Bar.__bases__)#(<class '__main__.Foo'>,)

    七、在多继承背景下的属性查找

    在菱形继承的背景下:查找属性

    1、经典类:深度优先(没有继承object的类以及子类)

    2、新式类:广度优先(继承object的类以及子类)

    八、super()依赖继承

    super()会严格按照mro列表从当前查找的位置继续往后查找

    class A:
        def test(self):
            print('A.test')
            super().test()
    class B:
        def test(self):
            print('from B')
    class C(A,B):
        pass
    
    c1=C()
    print(C.mro())
    #[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    c1.test()
    #A.test
    #from B
  • 相关阅读:
    AIR 访问网络资源老提示 Unhandled ioError 错误的解决办法
    Flex组件 EWindow 和 TimerStepper
    获取Flex SDK加载进度的方法
    我的第一个ANE程序
    给flex的自定义组件分类,使自定义组件放到组件面板的不同文件夹下!
    The status code returned from the server was: 500
    如何有效编写软件的75条建议
    让上帝讲真话——谈客户访谈思路
    C#之虚函数
    向您推荐几个虚拟化技术的BLOG(5.8日增加)
  • 原文地址:https://www.cnblogs.com/happyfei/p/9545363.html
Copyright © 2011-2022 走看看