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
  • 相关阅读:
    序列JSON数据和四种AJAX操作方式
    jquery.validate和jquery.form.js实现表单提交
    JQuery Validate使用总结1:
    HOWTO: Include Base64 Encoded Binary Image Data (data URI scheme) in Inline Cascading Style Sheets (CSS)(转)
    SharePoint 2007 使用4.0 .Net
    动态IP解决方案
    取MS CRM表单的URL
    从Iframe或新开的窗口访问MS CRM 2011(转)
    Toggle or Hidden MS CRM Tab
    Windows 2008下修改域用户密码
  • 原文地址:https://www.cnblogs.com/happyfei/p/9545363.html
Copyright © 2011-2022 走看看