python面向对象学习三 --多继承+装饰器写多继承+Mixin多继承

多继承

OCP原则: 多用继承,少修改
补充
OCP – Open -closed Principle (开闭原则)
应该在不修改现有代码的基础上,引入新的功能

继承的用途: 在子类上实现对基类的增强,实现多态

多态

在面向对象中,父类,子类通过继承联系在一起,如果可以通过一套方法,就可以实现不同表现,就是多态
一个类继承自多个类就是多继承,它将具有多个类的特征

多继承的弊端

多继承很好的模拟了世界,因为事物很少是单一继承,但是舍弃简单,必然引入复杂性,带来了冲突.

多继承的实现会导致编译器设计的复杂增加,所以有些高级编程语言舍弃了类的多继承

C++支持多继承,Java 舍弃了多继承

Java 中,一个类可以实现多个接口,一个接口也可以继承多个接口,Java 的接口很纯粹,只是方法的声明,继承者必须实现这些方法,就具有了这些能力,就能干什么

多继承可能会带来二义性, 比如一个类多继承了猫和狗的类,那子类究竟继承谁的叫声shout呢?

python 多继承的实现

class ClassName(基类列表):

​ 类体

在上图中,左图是多继承(菱形继承),右图是单一继承

多继承带来了路径选择问题,究竟继承哪个父类的特征呢?

Python 中使用MRO(method reslution order 方法解析顺序)解决基类搜索顺序问题

采用C3算法: 在类被创建出来的时候,就计算一个MRO有序列表,C3算法解决了多继承的二义性.

C3算法,解决了继承的单调性,它阻止创建之前版本产生的二义性,求得MRO本质是为了线性化,且确定了顺序.

单调性:假设有A,B,C三个类,C的mro是[C,A,B],那么C的子类mro,A,B的顺序一定是单调的

多继承的缺点

当类很多,继承复杂情况下,继承路径太多,很难说清什么样的继承路径
Python 语法是允许多继承,但Python代码的解释执行,只有执行到时才会发现错误,

因此,在使用过程中,应该尽量避免使用多继承

Mixin

首先看一个类子:

首先有一个基类 Document ,Word 与Pdf 都是其子类

现有如下需求:

在Document 中提供print方法

class Document:
    def __init__(self,content):
        self.content=content
    def print(self):
        print(self.content,'in word')
class Word(Document):pass
class Pdf(Document):pass
w  = Word('test word string',)
##################
class Document:
    def __init__(self,content):
        self.content=content
    def print(self):
        print(self.content,'in word')
class Word(Document):
    def print(self):
        print(self.content,'in word')
class Pdf(Document):
    def print(self):
        print(self.content,'in pdf')
w  = Word('test word string',)

基类提供的方法可以不具体实现,因为它未必适合子类的打印,子类中需要覆盖重写

基类中只定义,不实现的方法称为"抽象方法,在Python中,如果采用这种方式定义的抽象方法,子类可以不实现,直到子类使用该方法的时候才报错

#父类做统计基本实现
class Document:  # 抽象类 
    def __init__(self ,content):
        self.content = content
    def print(self):
        raise NotImplementedError('我就不实现')   # 未实现异常 往往含有此方法,代表该类做为基类,因此该类就变成了抽象类
class Word(Document):  # 省掉了不必要的方法 
    def print(self): # 这里不是全局的print 
        print(self.content,'~~in word')
class Pdf(Document):
    def print(self):
        print(self.content,'~~in pdf')
w = Word('test word string')
d =Document('tset string') # 内部含有未实现异常,但是不影响实例化,但不建议对其实例化
#抽象类不实例化,所以下面的子类同样可以对其实例化.但不是一定要实例化.
# 子类覆盖抽象类

需要打印的子类上增加

如果在现有子类word 或PDF上直接增加,违反了OCP原则,所以可以继续在后面增加子类来完成打印功能

class Document: # 第三方库,不允许修改
    def __init__(self, content):
        self.content = content
class Word(Document)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值