python面向对象(类的多继承)

多继承

ocp原则:多用“继承”,少修改
继承的用途:在子类上实现对基类的增强、实现多态

多态:通过一套方法,实现不同表现。
一个类继承自多个类就是多继承,它将具有多个类的特征。

多继承弊端

C++支持多继承;Java舍弃了多继承
多继承可能会带来二义性,例如,猫和狗都继承自动物类,现在如果一个类多继承了猫和狗类,猫和狗都有shout 方法,子类究竟继承谁的shout呢? 除非万不得已,能不用就不用,会造成代码不可控

解决方案:解决多继承的语言,要解决二义性。深度或者广度优先
Python使用MRO(method resolution order方法解析顺序 类属性的解释顺序)解决基类搜索顺序问题。
MRO三个搜索算法:都是深度优先

  1. 新式类算法,经典算法的升级,深度优先,重复的只保留最后一个没有解决继承的单调性
  2. C3算法,在类被创建出来的时候,就计算出一个MRO有序列表。解决了继承的单调性

Mixin
需求:为Document提供print方法

class Document:
    def __init__(self, content):
        self.content = content
    def print(self):  # 抽象方法 只定义,不实现,直到子类使用该方法的时候才报错
        raise NotImplementedError()
class Word(Document): pass
#   def prints(self):
#        print('test',self.content)
class Pdf(Document): pass
t = Word() # 实例化
t.prints()

#用装饰器增强一个类,把功能给类附加上去,哪个类需要,就装饰他(就比如我要在Word函数里面打印他的名字)
class Document:
    def __init__(self, name):
        self.name = name
    # def prints(self): # 抽象类
    #     raise NotImplementedError


class Word(Document): pass  # 如果这个是第三方库不能用的话,就要继承他然后再里面操作

def printname(cls):  # 我是一个装饰器 代表一个类就是cls,约定俗成。 
    def print_name(self):
        print('The document name is : {}'.format(self.__class__))

    cls.print = print_name  # 一个类里的打印属性(方法)等于一个函数(function)
    return cls  # 把函数返回 Worable 还是原来的值,只不过额外加了属性
    
@printname  # Wordable  = printname(Wordable)
class Wordable(Word): pass
test = Wordable(1)
test.print()
print(Wordable.mro()) # 显示方法查找顺序,基类的元组

除了用装饰器,还可以用Mixin方法,也可以得到同样的效果,但是Mixin是类,可以继承。

装饰器和Mixin两者的区别
装饰器是修改当前类,Mixin是继承 多了一个父类

Mixin使用原则

  1. 不应该显示的出现_/_init__初始化方法
  2. 不能独立的工作
  3. Mixin类的祖先类也应是Mixin类

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

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


class Word(Document): pass  # 如果这个是第三方库不能用的话,就要继承他然后再里面操作


class PrintableMixin: # Mixin方法
    def print(self):
        print(self.name, 'Mixin')


class Wordable(PrintableMixin, Word): pass # Mixin类通常在继承列表的第一个位置


test = Wordable(1)
test.print()
print(Wordable.mro())  # 查找循序

练习:
1、Shape基类,要求所有子类都必须提供面积的计算,子类有三角形、圆。
2 、对圆进行 json 序列化 Mixin 实现,和用装饰器实现

import math
class Shape:
    def area(self):  # 抽象类
        raise NotImplementedError()
        
class Triangle(Shape):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def area(self):
        p = (self.a + self.b + self.c) / 2
        return math.sqrt(p * (p - self.a) * (p - self.b) * (p - self.c))
import json



class Circle(Shape):
    def __init__(self, r):
        self.r = r

    def area(self):
        return math.pi * (self.r ** 2)


class CiccleshapeMixin:  # 定义一个mixin类
    def dums(self, t='json'):
        if t == 'json':
            return json.dumps(self.__dict__)
        else:
            pass
class Cir(CiccleshapeMixin,Circle):pass # 继承并发扬光大
a = Cir(4)
print(a.area())
print(a.dums())

----
def jsos(cls): # 装饰器实现
    def jss(self):
        return json.dumps(self.__dict__)
    cls.print = jss
    return cls

@jsos  # jsos = jsos(Circle)
class Circle(Shape):

if __name__ = __main__:
a = Circle(4)
print(a.area(), a.print())

2.用面向对象实现Linkedlist链表
1.单向链表实现append、iternodes方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值