python学习 day20 (3月27日)----(单继承多继承c3算法)

 继承

    提高代码的重用性,减少了代码的冗余
  这两个写法是一样的

  Wa('青蛙').walk()    #青蛙 can walk
  wa = Wa('青蛙')
  wa.walk()           #青蛙 can walk  
View Code
1.单继承
麻烦的写法(为什么要有单继承)
  如果多个类相似的情况下(每个都写一遍有大量重复 浪费麻烦)
class Tiger(object):
    def __init__(self,name):
        self.name = name
    def walk(self):
        print('%s can walk'%self.name)
    def swim(self):
        print('%s can swim'%self.name)
Tiger('老虎').walk()
class Swan(object):
    def __init__(self,name):
        self.name = name
    def walk(self):
        print('%s can walk'%self.name)
    def fly(self):
        print('%s can fly'%self.name)
Swan('鹦鹉').fly()
class Wa(object):
    def __init__(self,name):
        self.name = name
    def walk(self):
        print('%s can walk'%self.name)
    def swim(self):
        print('%s can swim' % self.name)
Wa('青蛙').walk()    #青蛙 can walk
wa = Wa('青蛙')
wa.walk()           #青蛙 can walk
class Er(object):
    def __init__(self,name):
        self.name = name
    def walk(self):
        print('%s can walk'%self.name)
    def swim(self):
        print('%s can swim' % self.name)
    def fly(self):
        print('%s can fly'%self.name)

# Er('天鹅').swim()
Er('天鹅').fly()

继承

  创建一个父类

  子类用父类的属性和方法 因为都差不多

  子类也可以新建自己特殊的属性和方法,通过super().__init__(相同元素) 和 父类名.__init__(self,相同元素)

  方法的话  自己新建 不必返回父类

class Animal(object):
    def __init__(self,name,kind):
        self.name = name
        self.kind = kind            #多了不是很好
    def walk(self):
        print('%s can walk'%self.name)
    def swim(self):
        print('%s can swim' % self.name)
    def fly(self):                  #可以有任意个
        print('%s can fly'%self.name)
class Tiger(Animal):pass
class Bird(Animal):
    def __init__(self,name,kind,eyes_color):  #小心 元素必须与父类相同
        # super().__init__(name,kind)
        # super(Bird,self).__init__(name,kind)  #注意 括号前面的元素是子类 当前类  告诉父类
        Animal.__init__(self,name,kind)     #注意 没有括号
        self.eyes_color = eyes_color  #自己的属性 自己赋值
    def say(self):
        print("%s can say like people"%self.name)
laohu = Tiger('老虎','')      # 实参与形参一一对应  即动物的属性此对象都有 也麻烦
print(laohu.walk(),laohu.fly(),laohu.name)        # 父类的方法和属性都可以用了 继承
yingwu = Bird('鹦鹉','','blue')      # 最好变量名 有意义  不是 abcd 。。。
print(yingwu.fly(),yingwu.eyes_color,yingwu.say())

 多继承

引子:

各种动物,每一种动物都是一个类
青蛙、天鹅、老虎、鹦鹉
青蛙 :走,游泳
天鹅 :走,游泳,飞
老虎 :走,游泳
鹦鹉 :走,飞,说话
class FlyAnimal:
    def fly(self):pass
class SwimAnimal:
    def swim(self):pass
    def eat():pass
class WalkAnimal:
    def walk(self):pass
    def eat():pass

class Frog(SwimAnimal,WalkAnimal): pass
class Tiger(SwimAnimal,WalkAnimal):pass
class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass
class Parrot(FlyAnimal,WalkAnimal):
    def talk(self):
        pass
View Code

class Frog(SwimAnimal,WalkAnimal): pass
class Tiger(SwimAnimal,WalkAnimal):pass
class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass
class Parrot(FlyAnimal,WalkAnimal):
def talk(self):
  pass

多继承 是python语言中特有的继承方式
java语言中不支持多继承的,C# 也不支持多继承
C++支持多继承
c c++ c# java

多继承和单继承是一样的
    如果对象使用名字
    是子类中有的,那么一定用子类的
    子类没有,可以到多个父类中去寻找
如果多个和父类都有,那么用谁的
 如果父类子类都想用,super(),父类名.方法名
算法:
1钻石继承问题

代码实现:
钻石继承问题
class A(object):
    def func(self):
        print('a')
class B(A):
    # def func(self):
    #     print('b')
class C(A):
    # def func(self):
    #     print('c')
class D(B,C):
    # def func(self):
    #     print('d')
d = D()
d.func()
View Code

  逐个隐藏 函数 来查看调用顺序

 

# super().func() 左想
class A(object):
    def func(self):
        print('a',end='')

class B(A):
    pass
    def func(self):
        super().func()
        print('b',end='')

class C(A):
    pass
    def func(self):
        super().func()
        print('c',end='')

class D(B,C):
    pass
    def func(self):
        super().func()
        print('d',end='')

b = B()
b.func()
print()
d = D()
d.func()
# 在多继承中,super就只和mro顺序有关系,和父类子类没有关系了
View Code
2乌龟继承顺序

代码实现:
乌龟继承问题
class A(object):
    def func(self):
        print('a')

class B(A):
    pass
    # def func(self):
    #     print('b')

class C(A):
    pass
    # def func(self):
    #     print('c')
class D(B):
    pass
    # def func(self):
    #     print('d')
class E(C):
    pass
    # def func(self):
    #     print('e')

class F(D,E):
    pass
    # def func(self):
    #     print('f')
f = F()
f.func()
View Code

 过程实现:

# C3算法
# A= [AO]
# B = B ,B节点的父类对应的顺序
# B = B ,A节点顺序
# B = B ,[AO]
# 提取第一个点
    # 如果从左到右第一个类,
    # 在后面的继承顺序中也是第一个,或者不再出现在后面的继承顺序中
    # 那么就可以把这个点提取出来,作为继承顺序中的第一个类
# B = [AO]
# BA = [O]
# B这个节点的继承顺序 :[BAO]
# C = C,[AO]
# C = [AO]
# CA = [O]
# C这个节点的继承顺序 :[CAO]
# l(D) = D + [BAO]
# D = [BAO]
# [DBAO]

# l(E) = E + [CAO]
# [ECAO]

# L[F] = F,[BAO],[ECAO]
# [F] = [DBAO],[ECAO]
# [FD] = [BAO],[ECAO]
# [FDB] = [AO],[ECAO]
# [FDB] = [AO],[ECAO]
# [FDBE] = [AO],[CAO]
# [FDBEC] = [AO],[AO]
# [FDBECA] = [O],[O]
# [FDBECAO]
View Code
广度优先
    C3算法
99%的情况都可以用眼睛看出来
但是仍然有1%的情况是看不出来的

C3算法是怎么计算的
C3算法代码实现
class A(object):
    def func(self):
        print('a')

class B(A):
    pass
    def func(self):
        print('b')

class C(A):
    pass
    def func(self):
        print('c')
class F:
    pass
    def func(self):
        print('f')

class D(A,F):
    pass
    # def func(self):
    #     print('d')
class E(B,C,F):
    pass
    def func(self):
        print('e')
class G(C,D):
    pass
    def func(self):
        print('g')
class H(E,G):
    pass
    def func(self):
        print('h')
print(H.mro())   # 就是帮助我们来展示c3算法的继承顺序
View Code

 在python2.7中

  主动继承object才是新式类,默认是经典类
# coding:utf-8
# 新式类 继承object
# 经典类 只在py2.x中有 默认不继承object
# 多继承
# 遵循的是深度优先
class A:pass
    # def func(self):
    #     print('a')
class B(A):
    pass
    # def func(self):
    #     print('b')
class C(A):
    pass
    def func(self):
        print('c')
class D(B,C):pass
    # def func(self):
    #     print('d')
d = D()
d.func()
View Code

继承总结

单继承
子类有的就用子类的
没有的就用父类的
如果父类子类都想用,super(),父类名.方法名
多继承
新式类 :
继承object
py2 要主动继承object才是新式类,默认是经典类
python2 必须 super(现在类,self) 传给父类(object)
遵循的是广度优先算法,C3算法
有super()的,super遵循mro顺序的
有mro()方法

经典类 :
不继承object
多个类之间去寻找方法的时候遵循深度优先
没有super方法
也没有mro
只在python2 中存在

 人狗大战:

  继承写法

class Animal(object):
    def __init__(self,name,blood,ad):
        self.name = name
        self.hp = blood
        self.ad = ad
class Dog(Animal):
    def __init__(self,name,blood,ad,kind):
        super().__init__(name,blood,ad)
        self.kind = kind

    def bite(self,person):
        person.hp -= self.ad
        print('%s攻击了%s,%s掉了%s点血' % (self.name, person.name, person.name, self.ad))

class Person(Animal):
    def __init__(self,name,hp,ad,sex):
        super().__init__(name,hp,ad)
        self.sex = sex

    def fight(self,dog):
        dog.hp -= self.ad
        print('%s攻击了%s,%s掉了%s点血'%(self.name,dog.name,dog.name,self.ad))

hei = Dog('小黑',300,20,'哈士奇')
alex = Person('alex',20,1,'不详')
alex.fight(hei)
print(hei.hp)
hei.bite(alex)
print(alex.hp)



# 抽象
# 继承

# 组合 :什么有什么
# 继承 :什么是什么的关系
    # 先想描述的对象
    # 先写出对象所对应的类
    # 发现多个类之间有相同的代码
    # 把相同的代码提取出来,搞成一个父类

# 先抽象,再继承
# 对象 -->类 -->基类
# 基类 -继承-> 子类 -实例化-> 对象
View Code


原文地址:https://www.cnblogs.com/Doner/p/10605655.html