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

    面向对象——继承

    什么是继承?

    • 继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类。
    # 父类
    class Father1:
        x = 1
        pass
    class Father2:
        pass
    class Father3:
        pass
    # 子类
    class Sub(Father1, Father2, Father3):
        pass
    # 子类.__bases__ 查看父类
    print(Sub.__bases__)
    print(Sub.x)
    # 打印结果:
    # (<class '__main__.Father1'>, <class '__main__.Father2'>, <class '__main__.Father3'>)
    # 1
    

    继承的作用?

    • 继承可以减少代码的冗余
    # 老师类
    class OldboyTeacher:
        school = 'oldboy'
        country = 'China'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        # 老师修改分数
        def change_score(self):
            print(f'老师 {self.name} 正在修改分数...')
    
    
    # 学生类
    class OldboyStudent:
        school = 'oldboy'
        country = 'China'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        # 学生选择课程
        def choose_course(self):
            print(f'学生 {self.name} 正在选择课程...')
    
    
    stu1 = OldboyStudent('YJG', 50, 'female')
    print(stu1.school, stu1.name, stu1.age, stu1.sex)
    
    tea1 = OldboyTeacher('tank', 17, 'male')
    print(tea1.school, tea1.name, tea1.age, tea1.sex)
    
    
    
    # 这里我们会发现上面代码会有很多重复的地方,下面我们就用继承
    # 定义父类People
    class People:
        school = "老男孩"
        country = "China"
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    # 老师类
    class OldboyTercher(People):
        def change_score(self):
            print(f"老师{self.name}正在修改分数")
    
    
    # 学生类
    class OldboyStudent(People):
        def choose_course(self):
            print(f"学生{self.name}正在选择课程")
    
    
    stu1 = OldboyStudent("张三", 18, "男")
    print(stu1.name, stu1.age, stu1.sex)
    tea1 = OldboyTercher("tank", 20, "男")
    print(tea1.name, tea1.age, tea1.sex)
    
    

    如何实现继承?

    • 先确认谁是子类谁是父类
    • 在定义子类时 子类名(父类名)

    怎么查看子类继承的那个父类?

    子类.__ bases __

    注意:在python中一个子类可以继承多个父类,其他语言中一个子类只有一个父类

    如何寻找继承关系?

    • 确认谁是子类
    • 确认谁是父类

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

    1、先从对象自己的名称空间查找

    2、对象中没有,从子类名称空间查找

    3、子类名称空间没有,从父类名称空间查找,没有就报错

    # 父类
    class Goo:
        x = 10
        pass
    # 子类
    class Foo(Goo):
        x = 100
        pass
    foo_obj = Foo()
    foo_obj.x = 1000
    print(foo_obj.x)
    print('对象的名称空间: ', foo_obj.__dict__)
    print('子类的名称空间: ', Foo.__dict__)
    print('父类的名称空间: ', Goo.__dict__)
    # 打印结果
    # 对象的名称空间:  {'x': 1000}
    # 子类的名称空间:  {'__module__': '__main__', 'x': 100, '__doc__': None}
    # 父类的名称空间:  {'__module__': '__main__', 'x': 10, '__dict__': <attribute '__dict__' of 'Goo' objects>, '__weakref__': <attribute '__weakref__' of 'Goo' objects>, '__doc__': None}
    

    就如下图:

    1574765820966

    派生

    • 派生指的是子类继承父类的属性和方法,并衍生出自己独有的属性和方法,这种情况就是派生。

      需要注意的是,当子类的名字和父类相同时,会优先使用子类的名字。

    # 父类
    class Foo:
        def f1(self):
            print("from Foo.f1....")
    
        def f2(self):
            print("from Foo.f2....")
            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()
    bar_obj.func()
    bar_obj.f2() 
    # 打印结果:
    # from Bar.f1....
    # from Bar.func....
    # from Foo.f2....
    # from Bar.f1....
    

    子类继承父类,派生出自己的属性与方法,并且重用父类的属性与方法

    怎么用呢?

    1、直接引用父类的__ init __为其传参,并添加子类的属性

    2、通过super来指向父类的属性

    ​ super()是一个特殊的类,调用super得到一个对象,该对象指向父类的名称空间

    注意:这两种方式使用哪一种都可以,但不可以混合使用

    # 方式一 __init__()方法
    class People:
        school = "oldboy"
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class OldboyTeacher(People):
        def __init__(self, name, age, sex, sal):
            People.__init__(self, name, age, sex)
            self.sal = sal
    
        def change_score(self):
            print(f"老师{self.name}修改分数...")
    
    
    class OldboyStudent(People):
        def __init__(self, name, age, sex, girl):
            People.__init__(self, name, age, sex)
            self.girl = girl
    
        def choose_course(self):
            print(f"学生{self.name}选择课程...")
    
    
    tea1 = OldboyTeacher("tank", 18, "男", 150000)
    print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    stu1 = OldboyStudent("张全蛋", 20, "男", "凤姐")
    print(stu1.name, stu1.age, stu1.sex, stu1.girl)
    
    
    # 方式二  super()方法
    class People:
        school = "oldboy"
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class OldboyTeacher(People):
        def __init__(self, name, age, sex, sal):
            super().__init__(name, age, sex)
            self.sal = sal
    
        def change_score(self):
            print(f"老师{self.name}修改分数...")
    
    
    class OldboyStudent(People):
        def __init__(self, name, age, sex, girl):
            super().__init__(name, age, sex)
            self.girl = girl
    
        def choose_course(self):
            print(f"学生{self.name}选择课程")
    
    
    tea1 = OldboyTeacher("tank", 25, "男", 15000)
    print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    stu1 = OldboyStudent("张全蛋", 18, "男", "凤姐")
    print(stu1.name, stu1.age, stu1.sex, stu1.girl)
    

    这里提一嘴经典类与新式类的知识(了解)

    新式类

    1、python2中凡是继承object的类或子孙类都是新式类

    2、python3中所有的类都默认继承object

    经典类

    1、python2中凡是没有继承object的类都是经典类

    2、python3中没有经典类

    在python3中提供了一个查找新式类查找顺序的内置方法

    mro():会把当前类的继承关系列出来

    多继承情况下造成"钻石继承"(菱形继承)

    mro查找顺序:

    ​ 新式类:广度优先

    ​ 经典类:深度优先

    # 新式类:
    # 这里只说新式类,博主电脑没装python2
    class A(object):
        def test(self):
            print('from A')
        pass
    
    class B(A):
        def test(self):
            print('from B')
        pass
    
    class C(A):
        def test(self):
            print('from C')
        pass
    class D(B):
        def test(self):
            print('from D')
        pass
    
    class E(C):
        def test(self):
            print('from E')
        pass
    
    class F(D, E):
        def test(self):
            print('from F')
        pass
    
    # F-->D-->B-->E-->C-->A-->object
    print(F.mro())
    # 打印结果:
    # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
    

    实在不太理解还有图

    1574765137491

  • 相关阅读:
    Spring AOP 代理创建方式
    VS全局搜索
    uni-app中添加AES加密
    中国菜刀"连接被重置"问题解决
    Windows go get下载包失败问题解决
    搭建vulhub 漏洞环境及安装Docker和docker-compose
    DedeCMS 5.7通用重装漏洞分析
    各就各位,预备,GO!
    ARL资产灯塔系统分组资产导出脚本
    玩《巫师3》需要了解的背景知识
  • 原文地址:https://www.cnblogs.com/aheng/p/11937988.html
Copyright © 2011-2022 走看看