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

一、继承

类的继承跟现实生活中的父子、孙子、重孙子等一样,父类又被称为基类

在python中继承分为单继承和多继承

class Father:
    pass

class Mother:
    pass

class Son(Father): #单继承
    pass

class Son(Father, Mother): #多继承(可以不止两个)
    pass

子类集成了父类的所有类属性

class Father:
    money = 100
    def __init__(self,name, age):
        self.name = name
        self.age = age

    def play_son(self):
        print("%s正在打儿子"%self.name)

class Son(Father):
    pass
f1 = Father("蔡徐坤","30")

print(Son.money)
Son.play_son(f1)

子类定义的属性如果跟父类同名了,优先拿自己定义的值

class Father:
    money = 100
    def __init__(self,name, age):
        self.name = name
        self.age = age

    def play_son(self):
        print("%s正在打儿子"%self.name)

class Son(Father):
    money = 10
    def play_son():
        print("测试")
f1 = Father("蔡徐坤","30")

print(Son.money)
Son.play_son()

因为下面例子中Son没有init函数,所以实例化Son的时候会触发继承的父类的init,所以需要传入两个参数

class Father:
    money = 100
    def __init__(self,name, age):
        self.name = name
        self.age = age

    def play_son(self):
        print("%s正在打儿子"%self.name)

class Son(Father):
    money = 10

f1 = Father("蔡徐坤","30")

print(Son.money)
s1 = Son("自己", "18") #实例化Son的时候会触发继承的父类的init,所以需要传入两个参数
print(s1.name)
print(s1.__dict__)
print(Son.__dict__)

  

二、什么时候用继承?

1. 当类之间有显著不同时,并且较小的类是较大类所需要的组件时,用组合比较好

2. 当类之间有很多相同的功能来提取这些共同的功能做成基类,用继承比较好

派生:

一个类,继承了父类,而自己又有独特的功能称为派生

继承同时具有的两种含义:

1、继承基类的方法,并且做出自己的改变或扩展(代码重用)

#这种继承意义不大,甚至是有害的,因为它使得子类与基类出现强耦合,代码块之间往往越独立越好

2、声明某个子类兼容于某基类,定义一个接口类,子类继承接口,并且实现接口中定义的方法

三、【接口继承】

概念:定义一个基类,当基类当中把自己的方法定义成接口函数,利用装饰器的方式,

只要来一个子类继承它,就必须实现基类中的方法

接口:就是函数或者说方法

接口里的方法不用实现,只是为了规范子类。

 通过引入abc模块,强制子类的方法必须与基类一致,若不一致,则报错!

import abc
class All_file(metaclass = abc.ABCMeta):
    @abc.abstractclassmethod
    def read(self):
        pass
    @abc.abstractclassmethod
    def write(self):
        pass

class Disk(All_file):
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Cdrom(All_file):
    def read(self):
        print('cdrom read')
  #此处少定义一个write函数,所以会报错
c1 = Cdrom()

 

而Disk类中的方法与基类一致,则正常调用

import abc
class All_file(metaclass = abc.ABCMeta):
    @abc.abstractclassmethod
    def read(self):
        pass
    @abc.abstractclassmethod
    def write(self):
        pass

class Disk(All_file):
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Cdrom(All_file):
    def read(self):
        print('cdrom read')

d1 = Disk()
d1.read()

  

四、继承顺序

继承顺序分为两种:1. 深度优先  2. 广度优先

基类没有任何继承关系的叫 经典类

基类继承 object 的叫新式类

在python 3中,都是新式类,新式类按广度优先

class A:  #基类
    def test(sslf):
        print('A')
class B(A):
    def test(self):
        print('B')
class C(A):
    def test(self):
        print('C')
class D(C):
    def test(self):
        print('D')
class E(C):
    def test(self):
        print('C')

class F(D, E):
    def test(self):
        print('F')

f1 = F()
f1.test()

调用test方法时,先从自身开始找,找不到的话,找继承的父类,新式类按广度优先

F--->D--->B--->E--->C---->A

内置方法查看继承顺序

python到底是如何实现继承,对于你定义的每一个类,python会计算出一个方法解析(MRO)列表,

这个MRO列表就是一个简单的所有基类的线性顺序列表

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。

而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上

就是合并所有父类的MRO列表并遵循如下三条规则:

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

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

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

print(F.__mro__) 

而在python2中,有经典类之分,经典类继承按 深度优先

即:F--->D---->B--->A---->E----->C

 

猜你喜欢

转载自www.cnblogs.com/dabai123/p/11451958.html
今日推荐