面向对象 -- 三大特性之继承

什么是继承

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

输入没有指定父类,python的类会默认继承object类,object是所有python类的父类。

继承的优点

增强耦合性  节省代码  使代码更加规范

单继承

一个子类继承了一个父类

如果子类想使用一个名字

如果子类自己有,那就用自己的

如果子类自己没有,那就用父类的

如果父类也没有,就报错

如果想使用的名字子类和父类中都有

既想使用子类的,也想使用父类的 那就在子类的方法中使用

1.父类名.方法名(self.参数1,参数2)

2.super().方法名(参数1,参数2)

示例函数

class Animal(object):
    def __init__(self,name,kind):
        self.name = name
        self.kind = kind

    def eat(self,food):
        print('%s eat %s'%(self.name,food))

    def drink(self):
        print('%s drink water'%(self.name))

    def catch(self):
        print('%s catch mouse'%(self.name))


#
class Cat(Animal):
    def __init__(self,name,kind,eyes_color):
        self.eyes_color = eyes_color  # 派生属性
        # super(Cat,self).__init__(name,kind)
        super().__init__(name,kind)   # 相当于执行父类的init方法
        # Animal.__init(self,name,kind)

    def climb(self):              # 派生方法
        print('%s climb tree'%self.name)

class Dog(Animal):
    def chai(self):
        print('%s cha'%(self.name))


hua = Cat('小花','橘猫','蓝色')
hua.eat('小鱼干')
hua.climb()

组合和继承的区别:

组合是什么有什么

继承是什么是什么的关系

先想描述的对象

先写出对象所对应的类

发现多个类之间有相同的代码

把相同的类提取出来,搞成一个父类

先抽象 再继承

对象 -- 类 -- 父类

父类 -- (继承) -- 子类 -- (实例化) -- 对象

继承是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构

多继承

是python特有的

class ShenXian: # 神仙
    def fei(self):
        print("神仙都会⻜")
class Monkey: #
    def chitao(self):
        print("猴⼦喜欢吃桃⼦")
class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴
    pass
sxz = SunWukong() # 孙悟空
sxz.chitao() # 会吃桃⼦
sxz.fei() # 会⻜

如果对象使用名字,是子类中有的,那么一定用子类的

子类没有,可以到多个父类中去寻找

但如果多个父类中出现了重名的方法时,可以通过 mro() 方法来判断使用哪一个父类中的方法

钻石继承

 

查找方法顺序 D -- B -- C -- A

广度优先
    C3算法
99%的情况都可以用眼睛看出来
但是仍然有1%的情况是看不出来的

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算法的继承顺序


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,[DBAO],[ECAO]
[F] = [DBAO],[ECAO]
[FD] = [BAO],[ECAO]
[FDB] = [AO],[ECAO]
[FDB] = [AO],[ECAO]
[FDBE] = [AO],[CAO]
[FDBEC] = [AO],[AO]
[FDBECA] = [O],[O]
[FDBECAO]

以上算法也可以用  print(子类.mro()) 来完成  这个代码是用来帮助我们展示C3算法的继承顺序的

super的区别

单继承中的super就是找父类

多继承中的super找的时mro顺序的下一分类  super之和mro顺序有关  和父类子类无关

多继承种类的区别

新式类

所有的类继承的都是object

在python2x中 主动继承object的才是新式类,否则默认是经典类

遵循广度优先算法 C3算法

有 super 的类  super遵循mro顺序 有mro()方法

经典类

不继承object

多个类之间寻找方法时遵循深度优先

没有super方法 没有mro方法

原文地址:https://www.cnblogs.com/biulo/p/10609315.html