python类之继承 展开

一、继承概述

面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

继承概念的实现方式主要有2类:实现继承、接口继承。

实现继承是指使用基类的属性和方法而无需额外编码的能力。
接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)。

在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。

二、实现继承

简单的继承

class Person:
    def walk(self):
        print("person is walking")

class Man(Person):
    def talk(self):
        print("man is talking")

p1 = Man()
print(Man.__dict__)
p1.walk()
p1.talk()
####结果
#{'__doc__': None, 'talk': <function man.talk at 0x10330dae8>, '__module__': '__main__'}
#person is walking
#man is talking

可以看出Man类继承了Person类的方法,但是在Man类的属性字典中除了自己定义的talk方法并没有walk方法,因此只有子类中没有找到类似的方法时才会去父类中寻找

方法重写

class Person:
    def walk(self):
        print("person is walking")

class Man(Person):
    def walk(self):
        print("man is walking")
    def talk(self):
        print("man is talking")

p1 = Man()
x1 = Person()
p1.walk()
x1.walk()
####结果
#{'__doc__': None, 'talk': <function man.talk at 0x10330dae8>, '__module__': '__main__'}
#man is walking
#person is walking

子类可以对父类的方法进行重写,而不会覆盖父类的方法

使用父类的方法

方法一

父类名.方法名
class Car:
    def __init__(self,size,type,price):
        self.size = size
        self.type = type
        self.price = price

class Battery(Car):
    def __init__(self,size,type,price,battery):
        Car.__init__(self,size,type,price)
        self.battery = battery

    def show_info(self):
        print("%s的电池电量为%s"%(self.type,self.battery))

mycar = Battery('small','E1','100w','8000A/h')
mycar.show_info()
#E1的电池电量为8000A/h

使用此类调用父类的方法有缺陷,如果一个父类被若干个子类继承,父类一修改类名,则会导致代码有多处都需要修改,因此介绍方法二

方法二

super().方法名
class Car:
    def __init__(self,size,type,price):
        self.size = size
        self.type = type
        self.price = price

class Battery(Car):
    def __init__(self,size,type,price,battery):
        super().__init__(size,type,price) 
        #使用此种调用方法,也不用传入self参数
        self.battery = battery

    def show_info(self):
        print("%s的电池电量为%s"%(self.type,self.battery))

mycar = Battery('small','E1','100w','8000A/h')
mycar.show_info()
#E1的电池电量为8000A/h

三、接口继承

声明某个子类兼容于某个父类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法。
在实践中,接口继承比较常见并且实用,因为实现继承虽然减少了代码复用,但是这样子类和父类的耦合度较高。
而接口继承规定了一个兼容接口(接口就是一种方法),使得外部调用这可以使用统一的接口调用,这种方法叫做归一化设计。
linux中的一切皆文件,是此编程思想的最典型的例子。

import abc
class All_file(metaclass=abc.ABCMeta): # All_file为一个接口类
    @abc.abstractmethod #此装饰器是为了子类必须对此接口方法进行重写,否则无法进行实例化
    def read(self): # read为接口方法,没有任何实际方法
        pass

    @abc.abstractmethod
    def wirte(self): # 同样也是接口方法
        pass

class Disk(All_file):
    def read(self):
        print("Disk is reading")

    def wirte(self):
        print("Disk is wirteing")

class Mem(All_file):
    def read(self):
        print("Mem is reading")

    def wirte(self):
        print("Mem is wirteing")

四、继承顺序

若一个类继承了多个类,那么如果类在自己的类中找不到方法时,往父类中寻找方法的顺序是不同的。其中新式类和经典类的寻找顺序也不同

新式类指的是继承了object类的子类,而经典类在定义时没有继承任何类。在python3中定义的类都为新式类

#新式类的定义
class Nc(obejct):
	pass

#经典类的定义
class Ocpass

新式类的继承顺序

例子的继承显示

class A:
    def test(self):
        print("这是A的方法")

class B(A):
    def test(self):
        print("这是B的方法")

class C(A):
    def test(self):
        print("这是C的方法")

class D(B):
    def test(self):
        print("这是D的方法")

class E(C):
    def test(self):
        print("这是E的方法")

class F(D,E):
    def test(self):
        print("这是F的方法")
f1 = F()
print(F.__mro__) #这是新式类包含的一个内置属性,保存了继承顺序的元祖
#(<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

从例子可见新式类的继承顺序是,F-D-B-E-C-A,顶级的父类是最后被寻找的,另一种被广泛的说法说这叫做广度寻找

经典类的继承顺序

经典类的继承顺序和新式类不太一样 ,继承顺序为F-D-B-A-E-C,这一般被叫做深度寻找。先从一个分支直接寻找至顶级父类,若还没有得到结果,则寻找分支。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值