• 面向对象之继承


    一、组合

    1、定义:自定义类的对象作为类的属性

    A类的对象具备某一个属性,该属性的值是B类的对象
    基于这种方式就把A类与B类组合到一起
    对象既能使用A类中的数据与功能,也能使用B类中的数据与功能

    2、作用:组合与继承的作用一样,都是用来减少类与类之间的重复代码

    class Teacher:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    t1 = Teacher('Owen', 17)
    print(t1.name, t1.age)               # Owen 17
    print(type(t1.name), type(t1.age))   # <class 'str'> <class 'int'>
    
    class Student:
        # 学生可以有老师属性
        def __init__(self, name, age, teacher):
            self.name = name
            self.age = age
    
            # 自定义类的对象作为类的属性
            self.teacher = teacher
    
    stu = Student('Bob',18,t1 )
    # print(stu.__dict__)
    # {'name': 'Bob', 'age': 18, 'teacher': <__main__.Teacher object at 0x00000000021F7E10>}
    
    
    # 学生的年龄和姓名
    print(stu.name, stu.age)   # Bob 18
    # 学生的老师年龄和姓名
    print(stu.teacher.name, stu.teacher.age)  # Owen 17

    二、继承

    1、定义:一种关系,子类可以通过父类获取属性和方法          

    继承是一种新建类的方式,新建的类称为子类或派生类          

    父类又称为基类、超类    

    作用:子类可以“遗传”父类的属性,从而可以减少代码冗余 

    如何寻找继承关系:先抽象,再继承,继承描述的就是 一种父子关系/从属关系

    2、继承语法:

    class Foo1:
             pass
    
    class Bar(Foo1):
             pass
    
    class Bar:     # 在python3中没有继承任何类的类,默认继承object
             pass
    例:
    
    class People:
        def __init__(self, name):
            self.name = name
    
        def eat(self):
            print(self.name + '在吃饭')
    
    
    class Student(People):
        identify = '学生'
        # def __init__(self, name):
        #     self.name = name
    
        # def eat(self):
        #     print(self.name + '在吃饭')
    
    
    student = Student('Bob')
    student.eat()         # Bob在吃饭
    
    
    class Leader(People):
        # def __init__(self, name):
        #     self.name = name
        #
        # def eat(self):
        #     print(self.name + '在吃饭')
        pass
    
    
    leader = Leader('Yang')
    leader.eat()         # Yang在吃饭

    3、继承关系(继承规则):继承是类与类之间的关系,寻找这种关系需要先抽象再继承  

    ①父类的所有未封装的属性和方法,子类都能访问

    ②父类的所有封装的属性和方法,子类都不能访问 

          在外界通过子类或子类对象,不能访问    

          在子类内部也不能访问

    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')
    stu1 = Oldboystudent('alex', 73, 'female')
    
    print(tea1.name, tea1.age, tea1.sex)  # egon 18 male

    4、继承关系下的属性查找顺序:

    ①优先找自身,自身没有找父类

    ②父类没有找父类的父类

    ③一直找到最顶级的父类,如果还没有报错

    5、抽离和派生

    抽离:先有多个共有的类,抽出共性形成父类

    派生:子类定义的名字会覆盖父类的同名属性

    三、方法重写和重用

    1、重写:先写好父类的方法,由于父类方法的功能不满足子类需求

    子类可以重写父类方法:方法名与父类相同,自定义方法的实现体

    2、重用:还需要父类方法的功能,在父类方法功能基础上再添加新功能

    突破点:在子类中去调用父类的方法,还有保证调用者是子类(子类的对象)

    # 1、方法的重写
    class Sup:
        num = 10
        def test(self):
            print('test sup')
    
    class Sub(Sup):
        num = 100
        # 先写好父类的方法,由于父类方法的功能不满足子类需求,
        # 子类可以重写父类方法:方法名与父类相同,自定义方法的实现体
        def test(self):
            print('test sub')
    
    print(Sub.num)   # 100
    Sub().test()     # test sub
    
    
    
    # 2、方法的重用
    class Sup:
        def test(self):
            print('test sup')
    
    class Sub(Sup):
        pass
        # 重用:还需要父类方法的功能,在父类方法功能基础上再添加新功能
        # 突破点:在子类中去调用父类的方法,还有保证调用者是子类(子类的对象)
        def test(self):
            # python2中写法:super(Sub, self).test()
            # python3中简化写法
            super().test()
            print('test sub')
    
    Sub().test()    # test sub

    四、init结合super()

    super关键字 

    super()可以得到调用父级功能的对象,调用者还是子类对象 

    super()只能在子类的方法中使用

    uper()本质super(子类类名,当前对象)

    # 人类:只需要初始化 - name
    # 老师: 要初始化 - name salary
    # 学生: 要初始化 - name grade
    
    class Sup:
        def test(self):
            print(self)
    
        def __init__(self, name):
            self.name = name
    
    class Sub(Sup):
        # 有继承关系下,只要名字相同,即使产生不同,还是属于同一个方法
        def test(self, num):
            super().test()
            print(num)
    
        # 默认父级的__init__可以被继承过来,
        # 但是会出现子类对象的属性比父类多
    
        def __init__(self, name, salary):
            super().__init__(name)  # 父级有的共性功能通过super()交给父级做
            self.salary = salary  # 子类特有的自己来完成
    
    # Sub().test(10)
    # Sub().test()  # 使用还是使用自身带参的,不能使用父级不带参的
    # (本质名字相同就是一个,优先查找自己的)

    五、多继承

    1、简单的多继承

    属性的查找顺序:优先找自己的,如果没有,按照继承先后查找父级

    class A:
        name = 'A'
        num = 10
    
    class B:
        name = 'B'
        count = 100
    
    # 子类可以继承所有父类的所有可继承属性
    class C(A, B):  # 自己 => A => B
    
        pass
    
    print(C.num)      # 10
    print(C.count)    # 100
    print(C.name)     # A
    # 打印属性查找的顺序
    print(C.mro())
    # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

    2、复杂的多继承

    class A:
        name = "A"
    class B(A):
        name = "B"
    class C:
        name = "C"
    class D(C):
        name = "D"
    class E(B, D):
        name = "E"
    print(E.mro())
    # [<class '__main__.E'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.D'>, <class '__main__.C'>, <class 'object'>]
     

    3、新式类与经典类

    ①新式类:继承object的类及其子类都是新式类

    在python3中如果一类没有继承任何父类,那么默认继承object类,即在python3中所有的类都是新式类 

    ②经典类:(只在python2中才有)没有继承object的类及其子类都是经典类 

    ③二者的区分:在菱形继承下

    经典类:深度优先查找

    新式类:广度优先查找

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    print(Foo.__bases__)  # (<class 'object'>,)
    print(Bar.__bases__)  # (<class '__main__.Foo'>,)
  • 相关阅读:
    百度地图API示例之小实践 添加代理商标注
    百度地图API示例之文本标注
    百度地图API示例之添加自定义控件
    百度地图API示例之添加定位相关控件
    linux crontab 计划任务 atd和windows下的计划任务
    转:PHP教程之PHP调用session_start后页面始终加载的问题研究
    PHP使用empty检查函数返回结果时报Fatal error: Can't use function return value in write context的问题
    Linux命令之yes
    转:Yii实战中8个必备常用的扩展,模块和widget
    转:Yii 常量的轻松管理
  • 原文地址:https://www.cnblogs.com/zhangguosheng1121/p/10742383.html
Copyright © 2020-2023  润新知