首页 > 其他 > 详细

OOP三大特征之继承

时间:2019-07-26 00:47:42      阅读:88      评论:0      收藏:0      [点我收藏+]
  • 继承

  • 什么是继承:两个对象之间的关系,一个称为子类,一个称为父类,其中子类继承着父类的属性以及方法技能,可以直接使用。(值得注意的是:在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.如果对下一个类存在两个合法的选择,选择第一个父类

 

OOP三大特征之继承

原文:https://www.cnblogs.com/ITchemist/p/11247632.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!