继承||派生||继承实现原理

继承

继承:是类与类之间的关系

是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可以成为基类或超类,新建的类称为派生类或子类

class ParentClass1: # 父类,基类,超生类
    pass

class ParentClasss2:
    pass

class SubClass1(ParentClass1): #子类,派生类
    pass

class SubClass2(ParentClass1,ParentClasss2):
    pass

# print(SubClass1.__bases__) #查看所继承的父类
# print(SubClass2.__bases__)

属性查找联系

#在查找属性的时候,显示从对象里面寻找,之后去类中寻找,最后去父类中寻找
class Foo:
    def f1(self):
        print("from Foo.f1")
    def f2(self):
        print("from Foo.f2")
        self.f1() # b.f1()

class Bar(Foo):
    def f1(self):
        print("frm Bar.f1")

b = Bar()
b.f2()

派生

当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

#派生:在查找属性的时候,显示从对象里面寻找,之后去类中寻找,最后去父类中寻找
class Hero:
    def __init__(self,name,damage,zing):
        self.name = name
        self.damage = damage
        self.zing = zing

    def attack(self,enemy):
        enemy.zing -= self.damage

class Yang(Hero):
    def attack(self,enemy):
        print("from Yang Class")
    pass

class Lin(Hero):
    pass

g1 = Yang('杨学伟',10,100)
r1 = Lin('林书行',100,200)
g1.attack(r1)

继承的实现原理

 

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

 

  1. 子类会先于父类被检查
  2. 多个父类会根据它们在列表中的顺序被检查
  3. 如果对下一个类存在两个合法的选择,选择第一个父类

 

python2中类主要分为两种

  • 新式类
  • 经典类

在python2中经典类:只要没有继承object的类,以及其他的子类都成为经典类

class Foo:
    pass

class Bar(Foo):
    pass

在python2中新式类:只要继承object的类,以及其他的子类都成为新式类

class Foo(object):
    pass

class Bar(Foo):
    pass

python3中的类只有一种新式类

#在python3中=》新式类:一个类没有继承object的类,默认就继承object
class Foo:
    pass
print(Foo.__bases__)

验证多继承下的属性查找

class A:
    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

f = F()
f.test()
#查找的顺序是F-D-B-E-C-A

总结:

经典类的查找属性的方法是深度优先

新式类的查找属性的方法是广度优先

 

 

posted @ 2018-03-17 20:31  Mr。yang  阅读(298)  评论(1编辑  收藏  举报