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

    1、什么是继承?

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

    # 将所有共有的属性与方法抽离出,形成父类
    # 父类是多个有共同点的普通类抽离共有属性与方法形成的类


    2.python中继承的特点:

      1 python中继承的特点:
      2         1. 子类可以遗传/重用父类的属性
      3         2. python中一个子类可以同时继承多个父类
      4         3. 在继承背景下去说,python中的类分为两种:新式类,经典类
      5             新式类: 但凡继承了object的类Foo,以及该类的子类...都是新式类
      6                 在python3中一个类即便是没有显式地继承任何类,默认就会继承object
      7                 即python3中所有的类都是新式类
      8 
      9             经典类:没有继承object的类,以及该类的子类...都是经典类
     10                 在python2中才区分新式类与经典类,
     11                 在python2中一个类如果没有显式地继承任何类,也不会继承object

    3 为何要用继承
        减少类与类之间代码冗余

    3 如何用继承

    # 继承的规则
    # 1.父类的所有未封装的属性和方法,子类都能访问
    # 2.父类的所有封装的属性和方法,子类都不能访问
    #       -- 在外界通过子类或子类对象,不能访问
    #       -- 在子类内部通过子类或子类对象也不能访问

    语法

      1 # class Parent1(object):
      2 #     pass
      3 #
      4 # class Parent2(object):
      5 #     pass
      6 #
      7 # class Sub1(Parent1):
      8 #     pass
      9 #
     10 # class Sub2(Parent1,Parent2):
     11 #     pass
     12 
     13 # print(Parent1.__bases__)
     14 # print(Parent2.__bases__)
     15 # print(Sub1.__bases__)
     16 # print(Sub2.__bases__)

    3.1利用继承来解决代码之间的冗余问题
    例子

      1 class OldboyPeople:
      2     school = 'Oldboy'
      3 
      4     def __init__(self,name,age,sex):
      5         self.name = name
      6         self.age = age
      7         self.sex = sex
      8 
      9 class OldboyStudent(OldboyPeople):
     10     # def __init__(self, name, age, sex, score=0):
     11     #     self.name = name
     12     #     self.age = age
     13     #     self.sex = sex
     14     #     self.score = score
     15 
     16     def choose_course(self):
     17         print('%s choosing course' % self.name)
     18 
     19 class OldboyTeacher(OldboyPeople):
     20     # def __init__(self,name,age,sex,level):
     21     #     self.name=name
     22     #     self.age=age
     23     #     self.sex=sex
     24     #     self.level=level
     25 
     26     def score(self,stu,num):
     27         stu.score=num
     28 
     29 
     30 stu1=OldboyStudent('刘二蛋',38,'male')
     31 print(stu1.__dict__)
     32 
     33 tea1=OldboyTeacher('egon',18,'male')
     34 print(tea1.__dict__)
     35 
    View Code

    3.2 父类功能的重用

    在子类派生出的新方法中重用父类功能的方式一:

    # 指名道姓地引用某一个类中的函数
    # 总结:
    # 1. 与继承无关
    # 2. 访问是类的函数,没有自动传值的效果

      1 class OldboyPeople:
      2     school = 'Oldboy'
      3 
      4     def __init__(self,name,age,sex):
      5         self.name = name
      6         self.age = age
      7         self.sex = sex
      8 
      9 class OldboyStudent(OldboyPeople):
     10     def __init__(self, name, age, sex, score=0):
     11         OldboyPeople.__init__(self,name,age,sex)
     12         self.score = score
     13 
     14     def choose_course(self):
     15         print('%s choosing course' % self.name)
     16 
     17 class OldboyTeacher(OldboyPeople):
     18     def __init__(self,name,age,sex,level):
     19         OldboyPeople.__init__(self,name,age,sex)
     20         self.level=level
     21 
     22     def score(self,stu,num):
     23         stu.score=num
     24 
     25 
     26 stu1=OldboyStudent('刘二蛋',38,'male')
     27 print(stu1.__dict__)
     28 
     29 tea1=OldboyTeacher('egon',18,'male',10)
     30 print(tea1.__dict__)
     31 
     32 
    View Code

    在子类派生出的新方法中重用父类功能的方式二:super()必须在类中用
     

      1 class Sup:
      2     def __init__(self, name):
      3         self.name = name
      4 
      5     def test(self):
      6         print(self)
      7 
      8 
      9 class Sub(Sup):
     10     # 默认父级的__init__可以被继承过来,
     11     # 但是会出现子类对象的属性比父类多
     12     def __init__(self, name, salary):
     13         super().__init__(name)  # 父级有的共性功能通过super()交给父级做
     14         self.salary = salary  # 子类特有的自己来完成
     15 
     16     # 有继承关系下,只要名字相同,即使参数不同,还是属于同一个方法
     17     def test(self, num):
     18         super().test()  # 使用父级的方法
     19         print(num)
     20 
     21 # 外界通过Sub对象来调用test方法,一定找自己的test方法(属性的查找顺序)
     22 
     23 
     24 # 重点:super() 可以得到调用父级功能的对象,调用者还是子类对象
     25 # 		-- super()只能在子类的方法中使用
     26 #		-- super()本质 super(子类类名, 当前对象)
     27 #		-- super().父类普通方法 | super().__init__() | super()能调用父类所有可继承方法
    View Code

    # 在python2中:super(自己的类名,自己的对象)
    # 在python3中:super()
    # 调用该函数会得到一个特殊的对象,该对象专门用来访问父类中的属性,!!!完全参照mro列表!!!!
    # 总结:
    # 1. 严格依赖继承的mro列表
    # 2. 访问是绑定方法,有自动传值的效果

      1 # class OldboyPeople:
      2 #     school = 'Oldboy'
      3 #
      4 #     def __init__(self,name,age,sex):
      5 #         self.name = name
      6 #         self.age = age
      7 #         self.sex = sex
      8 #
      9 # class OldboyStudent(OldboyPeople):
     10 #     def __init__(self, name, age, sex, score=0):
     11 #         super(OldboyStudent,self).__init__(name,age,sex)
     12 #         self.score = score
     13 #
     14 #     def choose_course(self):
     15 #         print('%s choosing course' % self.name)
     16 #
     17 # class OldboyTeacher(OldboyPeople):
     18 #     def __init__(self,name,age,sex,level):
     19 #         super().__init__(name,age,sex)
     20 #         self.level=level
     21 #
     22 #     def score(self,stu,num):
     23 #         stu.score=num
     24 
     25 
     26 # stu1=OldboyStudent('刘二蛋',38,'male')
     27 # print(stu1.__dict__)
     28 #
     29 # tea1=OldboyTeacher('egon',18,'male',10)
     30 # print(tea1.__dict__)
    View Code

    4.单继承背景下的属性的查找
         在单继承背景下属性的查找优先级:对象->对象的类->父类->父类.....

      1 class Foo:
      2     def f1(self):
      3         print('Foo.f1')
      4 
      5     def f2(self):
      6         print('Foo.f2')
      7         self.f1() #obj.f1()
      8 
      9 class Bar(Foo):
     10     def f1(self):
     11         print('Bar.f1')
     12 
     13 obj=Bar()
     14 obj.f2()
     15 '''
     16 Foo.f2
     17 Bar.f1
     18 '''
    View Code

    5

    # 在多继承背景下属性的查找优先级:
    # 如果一个子类继承多个分支(多个分支没有共同继承一个非object的类)
    # 此时属性的查找优先级是:对象->对象的类->按照从左往右的顺序一个分支一个分支的找下去

      1 
      2 # # 第四层:
      3 # class G:
      4 #     # x = 'G'
      5 #     pass
      6 #
      7 # # 第三层
      8 # class E(G):
      9 #     # x = 'E'
     10 #     pass
     11 #
     12 # class F:
     13 #     # x = 'F'
     14 #     pass
     15 #
     16 # # 第二层
     17 # class B(E):
     18 #     # x = 'B'
     19 #     pass
     20 #
     21 # class C(F):
     22 #     # x = 'C'
     23 #     pass
     24 #
     25 # class D:
     26 #     # x = 'D'
     27 #     pass
     28 #
     29 # # 第一层
     30 # class A(B, C, D):
     31 #     # x = 'A'
     32 #     pass
     33 #
     34 # obj = A()
     35 # # obj.x = 111
     36 # print(obj.x)
     37 
    View Code

    #菱形继承问题:
    # 新式类 : 广度优先查找,从左往右一个分支一个分支的查找,在最后一个分支才去查找顶级类
    # 经典类 : 深度优先查找,从左往右一个分支一个分支的查找,在第一个分支就查找顶级类

      1 class G(object):
      2     # x = 'G'
      3     pass
      4 
      5 # 第三层
      6 class E(G):
      7     # x = 'E'
      8     pass
      9 
     10 class F(G):
     11     # x = 'F'
     12     pass
     13 
     14 # 第二层
     15 class B(E):
     16     # x = 'B'
     17     pass
     18 
     19 class C(F):
     20     # x = 'C'
     21     pass
     22 
     23 class D(G):
     24     # x = 'D'
     25     pass
     26 
     27 # 第一层
     28 class A(B, C, D):
     29     # x = 'A'
     30     pass
     31 
     32 
     33 obj=A()
     34 # obj.x=111
     35 print(obj.x)
     36 #新式类(广度优先): obj->A->B->E->C-F->D->G->object
     37 #经典类(深度优先): obj->A->B->E->G->C-F->D
     38 
     39 # python专门为新式类内置了一个mro的方法,用来查看c3算法的计算结果,结果是??
     40 print(A.mro())
    View Code
  • 相关阅读:
    fatal error LNK1123: 转换到 COFF 期间失败:文件无效或损坏
    CI:模拟进化与遗传算法
    贝叶斯网络
    朴素贝叶斯模型
    概率与不确定性(乘法法则与贝叶斯法则)
    关于“启发式”搜索的一个形象解释
    Python 字符串与数字拼接报错
    无法启动此程序因为计算机中丢失 xxx.dll
    Python 以指定的概率选取元素
    验证码之SimpleCaptcha (二)
  • 原文地址:https://www.cnblogs.com/king-home/p/10759858.html
Copyright © 2011-2022 走看看