面向对象之多继承

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象之多继承相关的知识,希望对你有一定的参考价值。

多继承

  • Python不同版本的类

    Python2.2之前类是没有共同的祖先的,之后引入object类,它称为新式类.
    Python2中为了兼容,分为旧式类(古典类)和新式类
    Python3中全部都是新式类
    新式类都是继承自object的,新式类可以使用super.
  • 多继承

    OCP原则: 多继承、少修改
    继承的用途: 增强基类、实现多态

    多态
    在面向对象中,父类、子类通过继承联系在一起,如果通过同一个方法,实现了不同的表
    现,就是多态.就相与不同的实例使用同一方法,得到的结果不同.

    一个类继承自多个类就是多继承,它具备多个类的特征
  • 多继承的优缺点


    优点:
        多继承能更好的模拟现实世界
    缺点:
        多继承舍弃简单,引入复杂性,带来冲突

    示例:
        一个孩子继承父母双方的特征.那么他的眼睛是像爸爸还是妈妈呢?像谁的多一点
        呢?

    多继承的实现会导致编译器设计的复杂度增加,所以现在很多语言也舍弃了类的多继承
    C++支持多继承;Java舍弃了多继承
    Java中,一个类可以实现多个接口,一个接口也可以继承多个接口.Java的接口很纯粹,
    只是方法的声明,而让继承者来实现这些方法,于是具备了这些能力

    多继承可能会带来二义性,例如,一个类继承自猫和狗,猫和狗都有shout方法,那么子类
    是继承谁的shout方法呢?

    解决方案:
        实现多继承的语言,需要解决二义性,即继承的规范,是深度优先还是广度优先
  •  Python多继承实现


语法:

    class 类名(基类列表):

        语句块

   Python使用MRO(method resolusion order)解决基类搜索顺序问题



需求: 为Document子类提供打印功能

思路:

1 在基类中提供print方法

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

写,而且print算是一种能力–打印能力,不是所有的Document子类都需要.

2 在需要打印功能的子类上添加

如果直接在子类上增加,则违反了OCP原则,所以应该继承后添加


# 第一种思路实现
class Document: 
    def printable(self):
        print(‘Document‘)

class Word(Document):
    def printable(self):
        print(‘word‘)

class Pdf(Document): pass

Word().printable()
Pdf().printable()
# 第二种思路实现
class PrintableWord(Word):
    @classmethod
    def print(cls):        # print = classmethod(print)
        print(id(print))
        print(‘printword‘)

class Document: 
    def printable(self):
        print(‘Document‘)

class Word(Document): pass
class Pdf(Document): pass

PrintableWord().print()
print(PrintableWord.__dict__)
print(PrintableWord.__mro__)
第二种思路的缺陷在在于,如果需要更多功能的实现,有些类需要,而有些类不需要,
使用此方法,则会写很多类.
解决方案: 
    1. 可以使用装饰器,写一个功能就给一个类添加一个功能,不用此功能就取消装饰器,
    增添功能非常灵活
    2. 使用Mixin,多继承的思路,写一个类,有需要添加的功能,在将此类和需要功能的类
    组合在一起,也能解决此问题,并且类还可以继承


# 装饰器实现
# 装饰器函数,给类添加打印功能的属性
def printable(cls):
    cls.printable = lambda self: print(self.content)
    return cls

class Document: 
    def __init__(self,content):
        self.content = content

class Word(Document): pass
class Pdf(Document): pass
@printable
class PrintableWord(Word): pass

PrintableWord(‘word print‘).printable()
print(PrintableWord.__dict__)
print(PrintableWord.__mro__)


# Mixin实现
# Mixin实现附加打印功能

class Document: 
    def __init__(self,content):
        self.content = content

class Word(Document): pass
class Pdf(Document): pass

class PrintableMixin:
    def print(self):
        print(self.content,‘ Mixin‘)
class PrintableWord(PrintableMixin,Word): pass
PrintableWord(‘word print‘).print()
print(PrintableWord.__mro__)

# 通过继承Mixin,实现加强Mixin的打印功能
class SuperPrintableMixin(PrintableMixin):
    def print(self):
        print(‘strengthen‘)
        super().print()
        print(‘strengthen‘)
class PrintableWord(SuperPrintableMixin,Word): pass
PrintableWord(‘word print‘).print()
print(PrintableWord.__mro__)


  • Mixin类

    Mixin本质上就是多继承的实现
    Mixin体现的是一种组合的设计模式
    在面向对象的设计中,一个复杂的类,往往需要很多功能,而这些功能都来自不同的类,
    这就需要很多类组合在一起.
    从设计模式的角度来说,多组合、少继承

    Mixin类的使用原则
        1 Mixin类中不应该显示的出现__init__初始化方法
        2 Mixin类通常不能独立工作,因为它的作用是混入别的类中来实现部分功能
        3 Mixin类的祖先类也应该是Mixin类

    使用时,Mixin类通常在继承列表的第一个位置
        例如class PrintableWord(PrintableWord,word):pass

    组合的实现可以使用装饰器或Mixin,如果要使用继承的话,使用Mixin.


本文出自 “12064120” 博客,请务必保留此出处http://12074120.blog.51cto.com/12064120/1981086

以上是关于面向对象之多继承的主要内容,如果未能解决你的问题,请参考以下文章

python3 面向对象之多继承

面向对象之多继承

三. python面向对象

Python 面向对象 之 多继承 MRO

Python之路_Day7

VSCode自定义代码片段——JS中的面向对象编程