• 面向对象之继承与派生


    一、继承

    1、什么是继承

    继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父亲称之为基类或超类。
    - 在Python中,一个子类可以继承多个父类。
    - 在其它语言中,一个子类只能继承一个父类。

     如何实现继承

    class ParentClass1: #定义父类
        pass
    
    class ParentClass2: #定义父类
        pass
    
    class SubClass1(ParentClass1): #单继承,父类是ParentClass1,派生类是SubClass1
        pass
    
    class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
        pass
    
    SubClass1.__base__  #__base__只查看从左到右继承的第一个子类
    >>> (<class '__main__.ParentClass1'>,)
    SubClass2.__bases__  #__bases__则是查看所有继承的父类
    >>> (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

    要找出类与类之间的继承关系,需要先抽象,再继承。

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

    抽象即总结相似之处,总结对象之间的相似之处得到类,总结类与类之间的相似之处就可以得到父类,如下图所示

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

    1. 先从对象自己的名称空间中查找
    2. 对象中没有,从子类的名称空间中查找
    3. 子类中没有, 从父类的名称空间中查找,若父类没有,则会报错!

    三、派生:

    派生 指的是子类继承父类的属性与方法,并且派生出自己独有的属性与方法。
    若子类中的方法名与父类的相同,优先使用子类的。

    #父类
    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.f2()  #from foo.f2...
                  #from Bar.f1...
    问题:字类重写父类的__init__导致代码更加冗余:
    
    class BjdxPeople:
        school = 'Bjdx'
    
        def __init__(self,name,age,sex,sal):
            self.name = name
            self.age = age
            self.sex = sex
            self.sal = sal
    
    class BjdxTeacher(BjdxPeople):
    
        def __init__(self,name,age,sex,sal):
            self.name = name
            self.age = age
            self.sex = sex
            self.sal = sal
    
        def change_score(self):
            print(f'老师{self.name}修改分数...')
    
    class BjdxStudent(BjdxPeople):
        def __init__(self,name,age,sex,girl):
            self.name = name
            self.age = age
            self.sex = sex
            self.girl = girl
    
        def choose_course(self):
            print(f'学生 {self.name} 选择课程...')
    
    tea1 = BjdxTeacher('tank',66,'male',15000)
    stu1 = BjdxStudent('baohan',18,'male','小花')
    
    print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    print(stu1.name, stu1.age, stu1.sex, stu1.girl)
    '''
    解决问题: 子类重用父类的属性,并派生出新的属性。
        两种方式:
            1.直接引用父类的__init__为其传参,并添加子类的属性。
            2.通过super来指向父类的属性。
                - super()是一个特殊的类,调用super得到一个对象,该对象指向父类的名称空间。
                
            注意: 使用哪一种都可以,但不能两种方式混合使用。
    '''
    
    方式一:指名道姓地调用,(其实与继承是没有什么关系的)
    
    class BjdxPeople:
        school = 'oldboy'
    
        def __init__(self, name, age, sex):  # self == tea1, name == 'tank', age == 17, sex == 'male'
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class BjdxTeacher(BjdxPeople):
    
        # tea1, 'tank', 17, 'male', 15000000
        def __init__(self, name, age, sex, sal):
            # self.name = name
            # self.age = age
            # self.sex = sex
            # 类调用类内部的__init__,只是一个普通函数
            # BjdxPeople.__init__(tea1, 'tank', 17, 'male')
            BjdxPeople.__init__(self, name, age, sex)
            self.sal = sal
    
        def change_score(self):
            print(f'老师 {self.name} 修改分数...')
    
    
    class BjdxStudent(BjdxPeople):
    
        def __init__(self, name, age, sex, girl):
            
            BjdxPeople.__init__(self, name, age, sex)
            self.girl = girl
    
        def choose_course(self):
            print(f'学生 {self.name} 选择课程...')
    
    
    tea1 = BjdxTeacher('tank', 17, 'male', 15000)
    print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    
    
    stu1 = BjdxStudent('baohan', 28, 'male', '小花')
    print(stu1.name, stu1.age, stu1.sex, stu1.girl)
    方式二:super()调用,此方式(严格)依赖于继承
    super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性
    
    #了解:在python2中, 需要super(自己的类名,self)
    
    class BjdxPeople:
        school = 'Bjdx'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    class BjdxTeacher:
    
        def __init__(self,name,age,sex,sal):
    
            super().__init__(name,age,sex)
    
            self.sal = sal
    
        def change_score(self):
            print(f'老师 {self.name} 修改分数...')
    
    class BjdxStudent(BjdxPeople):
    
        def __init__(self, name, age, sex, girl):
            super().__init__(name, age, sex)
            self.girl = girl
    
        def choose_course(self):
            print(f'学生 {self.name} 选择课程...')
    
    
    tea1 = BjdxTeacher('tank', 17, 'male', 15000)
    print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    
    
    stu1 = BjdxStudent('baohan', 28, 'male', '小花')
    print(stu1.name, stu1.age, stu1.sex, stu1.girl)
  • 相关阅读:
    Creckme_Andrnalin.3
    逆向工程核心原理——第十三章
    Creckme_Andrnalin.2
    逆向工程核心原理——第十章
    第一个windows桌面应用程序
    逆向工程核心原理——第八章
    逆向工程核心原理——第七章
    逆向工程核心原理——第六章
    Creckme_6_aLoNg3x.1
    35. 搜索插入位置
  • 原文地址:https://www.cnblogs.com/wddxx/p/13670201.html
Copyright © 2020-2023  润新知