zoukankan      html  css  js  c++  java
  • OOP三大特征之继承

    • 继承

    • 什么是继承:两个对象之间的关系,一个称为子类,一个称为父类,其中子类继承着父类的属性以及方法技能,可以直接使用。(值得注意的是:在python3中所有创建的类都直接或间接,隐性或显性的继承object类,如果没有显示继承某个类,则默认继承的是object类,又称为新式类)

    • 为什么要使用继承:减少代码的复用

    • 用代码如何表示

    • class Base:
          character  = '我是父类'
          def want_basketball(self):
              print('教练我想打篮球')
      
      class SubClass(Base):               # 通过在子类的括号之中加父类的名称
          pass
      
      obj = SubClass()
      obj.want_basketball()               # 直接调用父类的方法 如果属性和方法完全一样的话
      print(obj.character)

      比如好人,坏人,黄种人,白种人,黑人都是人这个大类的继承,而他们都是抽象而生成人这个类的。

    • 那么当子类和父类有属性和方法有冲突时,是不是就不可以用继承方法呢?显然不是,一般来说我们可以将子类和父类的共同特征都提取出来,专业名词可以称之为抽象,将抽象完的一个新的类作为共同大类,供上述子类和父类使用。

    • 就以足球和篮球运动员为例,对于他们来说都是人类,都有名字性别和身高等特征,但是他们会的技能不一样
    • class Person:
          def __init__(self,name,height,gender):          # 定义抽象得来的公共类
              self.name = name
              self.height = height
              self.gender = gender
      
      class FootBallPlayer(Person):                       # 通过子类名括号里面加抽象父类名起到继承的作用
          def Skill(self):
              print('%s会踢足球'%(self.name))
      
      class BasketBallPlayer(Person):
          def Skill1(self):
              print('%s会打篮球'%(self.name))
      
      
      
      Kobe = BasketBallPlayer('kobe Bryant','189','male')     # 名字身高等信息就不需要通过父类调用,直接子类调用
      Kobe.Skill1()
      Messi = FootBallPlayer('Lion Messi','176','male')
      Messi.Skill()
    • 存在继承关系后的属性查找

    • 一个类必然继承另一个类,被继承的类也有可能继承了其他类,相当于C继承B,B又继承A

    • 此时查找属性的顺序是:

      对象本身的名称空间 - > 类的名称空间 -> 父类的名称空间 -> 父类的父类名称空间 ->...object类

      会沿着继承关系一直往后查找,直到找到为止,由于object是所有类的根类,所以如果找不着最后都会查找object类!

    • class Foo:
          def f1(self):
              print('Foo.f1')
      
          def f2(self):
              print('Foo.f2')
              self.f1()
      
      class Bar(Foo):
          def f1(self):
              print('Bar.f1')
      
      
      b=Bar()
      b.f1()
      #输出 Bar.f1
      b.f2()
      #输出 Foo.f2
    • 派生和覆盖

    • 派生的定义:当父类提供的属性无法完全满足子类的需求时,子类可以增加自己的属性或方法,或者覆盖父类已经存在的属性,此时子类称之为父类的派生类;

    • 覆盖的定义:如果子类中出现于与父类相同的属性以及方法时,程序要调用,会优先使用子类中的属性。
    • 很多情况下 子类中的代码与父类中仅有小部分不同,却不得不在子类定义新的方法,这时候可以在子类中调用父类已有的方法,来完成大部分工作,子类仅需编写一小部分与父类不同的代码即可

    • 有两种方式可以重用父类的属性和方法

    • 使用类名直接调用 ,该方式与继承没有关系,即时没有继承关系,也可以调用
    • 使用super()
    • class Person:
          def __init__(self,name,height,gender):          # 定义抽象得来的公共类
              self.name = name
              self.height = height
              self.gender = gender
      
      class FootBallPlayer(Person):                       # 通过子类名括号里面加抽象父类名起到继承的作用
          def __init__(self,name,height,gender,field):    # 如果不写这两行 将不能调用name height gender属性
              super().__init__(name,height,gender)        # 重用父类中的代码,防止覆盖了父类中的init方法
              self.field = field
          def Skill(self):
              print('%s会踢足球'%(self.name))
              print(self.height,self.gender,self.field)
      Messi = FootBallPlayer('Lion Messi','176','male','grass')
      Messi.Skill()
    • 组合

    • 当两个类之间没有太大的联系的时候,或者说它们不属于同类时,当一个对象要使用另一个对象的属性,这就叫做组合的概念。

    • class Equip:  # 武器装备类
          def fire(self):
              print('release Fire skill')
      
      
      class Riven:  # 英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类
          camp = 'Noxus'
      
          def __init__(self, nickname):
              self.nickname = nickname
              self.equip = Equip()  # 用Equip类产生一个装备,赋值给实例的equip属性
      
      
      r1 = Riven('锐雯雯')
      r1.equip.fire()  # 可以使用组合的类产生的对象所持有的方法
    • 继承实现的原理

    • class A(object):
          def test(self):
              print('from A')
      
      class B(A):
          def test(self):
              print('from B')
      
      class C(A):
          def test(self):
              print('from C')
      
      class D(B):
          def test(self):
              print('from D')
      
      class E(C):
          def test(self):
              print('from E')
      
      class F(D,E):
          # def test(self):
          #     print('from F')
          pass
      f1=F()
      f1.test()
      print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
      
      #新式类继承顺序:F->D->B->E->C->A
      #经典类继承顺序:F->D->B->A->E->C
      #python3中统一都是新式类
      #pyhon2中才分新式类与经典类
      
      继承顺序
    • 继承实质

    • python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
    • >>> F.mro() #等同于F.__mro__
      [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>
    • 所有父类的MRO列表并遵循如下三条准则:

      1.子类会先于父类被检查

      2.多个父类会根据它们在列表中的顺序被检查

      3.如果对下一个类存在两个合法的选择,选择第一个父类

  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/ITchemist/p/11247632.html
Copyright © 2011-2022 走看看