zoukankan      html  css  js  c++  java
  • 继承与派生

    一、继承

    1.什么是继承

    继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类。

    在python中,一个子类可以继承多个父类

    在其他语言中,一个子类只能继承一个父类

    2.继承的作用

    减少代码的冗余

    3.继承的实现

    先确认谁是父类,先抽象,再继承;谁是子类

     1 # 父类
     2 class Father1:
     3     x = 1
     4     pass
     5 
     6 class Father2:
     7     pass
     8 
     9 class Father3:
    10     pass
    11 
    12 
    13 # 子类
    14 class Sub(Father1):
    15     pass
    16 
    17 # 子类查看父类__bases__
    18 print(Sub.__bases__)
    19 # (<class '__main__.Father1'>,)
    20 print(Sub.x)
    21 # 1
     1 # 问题: 代码冗余
     2 # 老师类
     3 class OldboyTeacher:
     4     school = 'oldboy'
     5     country = 'China'
     6 
     7     def __init__(self, name, age, sex):
     8         self.name = name
     9         self.age = age
    10         self.sex = sex
    11 
    12     # 老师修改分数
    13     def change_score(self):
    14         print(f'老师 {self.name} 正在修改分数...')
    15 
    16 
    17 # 学生类
    18 class OldboyStudent:
    19     school = 'oldboy'
    20     country = 'China'
    21 
    22     def __init__(self, name, age, sex):
    23         self.name = name
    24         self.age = age
    25         self.sex = sex
    26 
    27     # 学生选择课程
    28     def choose_course(self):
    29         print(f'学生 {self.name} 正在选择课程...')
    30 
    31 
    32 stu1 = OldboyStudent('YJG', 50, 'female')
    33 print(stu1.school, stu1.name, stu1.age, stu1.sex)
    34 
    35 tea1 = OldboyTeacher('tank', 17, 'male')
    36 print(tea1.school, tea1.name, tea1.age, tea1.sex)

    解决代码冗余

     1 class People:
     2     school = 'oldboy'
     3     country = 'China'
     4 
     5     def __init__(self, name, age, sex):
     6         self.name = name
     7         self.age = age
     8         self.sex = sex
     9 
    10 class Student(People):
    11     # school = 'oldboy'
    12     # country = 'China'
    13 
    14     # def __init__(self, name, age, sex):
    15     #     self.name = name
    16     #     self.age = age
    17     #     self.sex = sex
    18     def func(self):
    19         print('from student')
    20 
    21 class Teacher(People):
    22     # school = 'oldboy'
    23     # country = 'China'
    24 
    25     # def __init__(self, name, age, sex):
    26     #     self.name = name
    27     #     self.age = age
    28     #     self.sex = sex
    29     def func(self):
    30         print('from teacher')
    31 
    32 
    33 s1 = Student('张三', 23, '')
    34 t1 = Teacher('李四', 25, '')
    35 
    36 print(s1.name, s1.age, s1.sex, s1.school)
    37 print(t1.name, t1.age, t1.sex, t1.school)

    4.继承的查找

    注意:程序的执行顺序是由上到下,父类必须定义在子类的上方

    在继承背景下,对象属性的查找顺序:
      1.先从对象自己的名称空间中查找
      2.对象中没有,从子类的名称空间中查找。
      3.子类中没有, 从父类的名称空间中查找,若父类没有,则会报错!

     1 # 父类
     2 class Father:
     3     x = 10
     4     pass
     5 # 子类
     6 class Sub(Father):
     7     x = 20
     8     pass
     9 sub_obj = Sub()
    10 
    11 # 此方法并未修改调用对象类的值,而是给调用产生的对象增加一个属性
    12 print('对象的名称空间:', sub_obj.__dict__)
    13 sub_obj.x = 30
    14 print(sub_obj.x)      # 30
    15 print('父类的名称空间:', Father.__dict__)
    16 print('子类的名称空间:', Sub.__dict__)
    17 print('对象的名称空间:', sub_obj.__dict__)
     1 # 父类
     2 class Father:
     3     x = 10
     4     pass
     5 # 子类
     6 class Sub(Father):
     7     x = 20
     8     pass
     9 sub_obj = Sub()
    10 # sub_obj.x = 30
    11 print(sub_obj.x)        # 20
    12 
    13 
    14 # 父类
    15 class Father:
    16     x = 10
    17     pass
    18 # 子类
    19 class Sub(Father):
    20     # x = 20
    21     pass
    22 sub_obj = Sub()
    23 # sub_obj.x = 30
    24 print(sub_obj.x)        # 10
    25 
    26 
    27 # 父类
    28 class Father:
    29     # x = 10
    30     pass
    31 # 子类
    32 class Sub(Father):
    33     # x = 20
    34     pass
    35 sub_obj = Sub()
    36 # sub_obj.x = 30
    37 print(sub_obj.x)        # 报错

    二、派生

    1.什么是派生

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

    2.派生的实现

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

     1 # 父类
     2 class Foo:
     3     def f1(self):
     4         print('from Foo.f1')
     5     def f2(self):
     6         print('from Foo.f2')
     7         self.f1()
     8 class Bar(Foo):
     9     # 重写
    10     def f1(self):
    11         print('from Bar.f1')
    12 
    13     def func(self):
    14         print('from Bar.func')
    15 bar_obj = Bar()
    16 
    17 bar_obj.f1()
    18 # from Bar.f1
    19 bar_obj.func()
    20 # from Bar.func
    21 bar_obj.f2()
    22 """
    23 输出结果:
    24     from Foo.f2
    25     from Bar.f1
    26 """

    问题:子类重写父类的__init__导致代码更加冗余

    class OldboyPeople:
        school = 'oldboy'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class OldboyTeacher(OldboyPeople):
    
        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 OldboyStudent(OldboyPeople):
    
        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 = OldboyTeacher('张三', 23, 'male', 1500)
    stu1 = OldboyStudent('李四', 28, '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得到一个对象,该对象指向父类的名称空间。

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

     1 # 方法一:
     2 class OldboyPeople:
     3     school = 'oldboy'
     4 
     5     def __init__(self, name, age, sex):
     6         self.name = name
     7         self.age = age
     8         self.sex = sex
     9 
    10 
    11 class OldboyTeacher(OldboyPeople):
    12 
    13     def __init__(self, name, age, sex, sal):
    14         OldboyPeople.__init__(self, name, age, sex)
    15         self.sal = sal
    16 
    17     #     self.name = name
    18     #     self.age = age
    19     #     self.sex = sex
    20     #     self.sal = sal
    21     def change_score(self):
    22         print(f'老师 {self.name} 修改分数...')
    23 
    24 
    25 class OldboyStudent(OldboyPeople):
    26 
    27     def __init__(self, name, age, sex, girl):
    28         OldboyPeople.__init__(self, name, age, sex)
    29         self.girl = girl
    30         # self.name = name
    31         # self.age = age
    32         # self.sex = sex
    33         # self.girl = girl
    34 
    35     def choose_course(self):
    36         print(f'学生 {self.name} 选择课程...')
    37 
    38 
    39 tea1 = OldboyTeacher('张三', 23, 'male', 1500)
    40 stu1 = OldboyStudent('李四', 28, 'male', '凤姐')
    41 print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    42 print(stu1.name, stu1.age, stu1.sex, stu1.girl)
     1 # 方法二
     2 class OldboyPeople:
     3     school = 'oldboy'
     4 
     5     def __init__(self, name, age, sex):
     6         self.name = name
     7         self.age = age
     8         self.sex = sex
     9 
    10 
    11 class OldboyTeacher(OldboyPeople):
    12 
    13     def __init__(self, name, age, sex, sal):
    14         super().__init__(name, age, sex)
    15         # self.name = name
    16         # self.age = age
    17         # self.sex = sex
    18         self.sal = sal
    19 
    20     def change_score(self):
    21         print(f'老师 {self.name} 修改分数...')
    22 
    23 
    24 class OldboyStudent(OldboyPeople):
    25 
    26     def __init__(self, name, age, sex, girl):
    27         super().__init__(name, age, sex)
    28         # self.name = name
    29         # self.age = age
    30         # self.sex = sex
    31         self.girl = girl
    32 
    33     def choose_course(self):
    34         print(f'学生 {self.name} 选择课程...')
    35 
    36 
    37 tea1 = OldboyTeacher('张三', 23, 'male', 1500)
    38 stu1 = OldboyStudent('李四', 28, 'male', '凤姐')
    39 print(tea1.name, tea1.age, tea1.sex, tea1.sal)
    40 print(stu1.name, stu1.age, stu1.sex, stu1.girl)

    3、新式类与经典类

    - 新式类:
      1.凡是继承object的类或子孙类都是新式类。
      2.在python3中所有的类都默认继承object。

    - 经典类:
      1.在python2中才会有经典类与新式类之分。
      2.在python2中,凡是没有继承object的类,都是经典类。

    mro的查找顺序:

    新式类:广度优先

    经典类:深度优先

    查找顺序可以从下图看出

  • 相关阅读:
    ASP Loading
    haproxy中两个常用的宏
    数字签名-摘要等
    haproxy内存管理-free_list原理
    haproxy-代码阅读-内存管理
    网卡中断不均衡处理
    TIME_WAIT 另一种解决方式 SO_LINGER
    HTTP报文格式
    TIME_WAIT过多及解决
    awk如何向shell传值
  • 原文地址:https://www.cnblogs.com/hexianshen/p/11937656.html
Copyright © 2011-2022 走看看