当前位置: 首页 > article >正文

python通过继承、组合、委托组织类

1 python通过继承、组合、委托组织类

#概念描述
1继承属性查找X.name
2多态方法调用X.method,取决于X的类型
3封装方法和运算符实现行为

通常来说,独特的运算使用独特的方法名称,不要依赖于调用标记。

python组织类结构的方式包括:继承、组合、委托。

1.1 继承:是一个关系

python的继承通过点号运算触发,比如X.name,在实例、类、超类中搜索属性。

#概念描述
1超类、基类、父类被继承的类
2派生类、子类继承的类
3派生父类向子类看
4继承子类项父类看

子类继承父类,子类和父类为“是一个(is-a)”关系,子类是父类的一种,子类是一个更具体,更全面的父类。

比如:员工是父类,清洁和扫地机器人工是子类,扫地机器人是清洁工,清洁工是一个员工。

示例

class Staff:#员工
    def __init__(self,name,salary=0):
        self.name=name
        self.salary=salary
    def payRaise(self,percent):
        self.salary=self.salary*(1+percent)
    def work(self):#干一些事情
        print(self.name,'does stuff')
    def __repr__(self):
        return '<Staff:name={},salary={}>'.format(self.name,self.salary)
        
class Cleaner(Staff):#保洁员
    def __init__(self,name):
        Staff.__init__(self,name,3000)
    def work(self):#打扫客房
        print(self.name,'cleaning guest rooms')

class Waiter(Staff):#前台服务员
    def __init__(self,name):
        Staff.__init__(self,name,5000)
    def work(self):#接待顾客
        print(self.name,'Receiving customers')

class SweepRobot(Cleaner):#扫地机器人
    def __init__(self,name):
        Staff.__init__(self,name,2000)
    def work(self):#打扫大堂
        print(self.name,'cleaning the lobby')
        
if __name__=='__main__':
    srb1=SweepRobot('robot1')
    print(srb1)
    srb1.work()
    srb1.payRaise(0.1)
    print(srb1);print()
    
    for klass in Staff,Cleaner,Waiter,SweepRobot:
        obj = klass(klass.__name__)
        obj.work()
        
'''E:\documents\F盘>python staffs.py
<Staff:name=robot1,salary=2000>
robot1 cleaning the lobby
<Staff:name=robot1,salary=2200.0>

Staff does stuff
Cleaner cleaning the office
Waiter Receiving customers
SweepRobot cleaning the lobby
'''

1.2 组合:有一个关系

python的组合类通过内嵌其他类的对象来实现自己的接口。

组合类有一个或多个内嵌类(组件类)的对象作为自己的属性。

组合类和内嵌类为“有一个(has a)”关系。

比如,酒店类(Hotel)有前台服务员(Waiter)和保洁员(Cleaner)两个类对象作为属性,实现酒店的退房操作。

from staffs import Waiter,Cleaner

class Customer:
    def __init__(self,name,roomNo):
        self.name=name
        self.roomNo=roomNo
    def checkOut(self,waiter):#退房
        print(self.name,'退房,房号为',self.roomNo)
    def backCard(self,waiter):#归还房卡
        print(self.name,'归还房卡给',waiter.name)
        
class Hotel:
    def __init__(self):
        #Hotel有 Waiter 和 Cleaner 类的对象
        self.waiter1 = Waiter('前台1号')
        self.cleaner1=Cleaner('保洁员1号')
    
    def checkOut(self,name,roomNo):#退房流程
        cust1=Customer(name,roomNo)
        cust1.checkOut(self.waiter1)
        cust1.backCard(self.waiter1)
        self.cleaner1.work()
        
if __name__ == '__main__':
        hot1=Hotel()
        hot1.checkOut('顾客1号','168')
'''E:\documents\F盘>python hotel.py
顾客1号 退房,房号为 168
顾客1号 归还房卡给 前台1号
保洁员1号 cleaning guest rooms
'''

1.3 继承组合例子

Processor内嵌reader和writer实例对象,为组合类,并且定义子类继承必须实现的方法converter,为转换器。

streams.py

from abc import ABCMeta,abstractmethod
class Processor:
    def __init__(self,reader,writer):#组合类
        self.reader=reader#读取器实例
        self.writer=writer#写入器实例
    def process(self):
        while 1:
            data=self.reader.readline()
            if not data:break
            data=self.converter(data)
            self.writer.write(data)
    @abstractmethod
    def converter(self,data):#继承,子类实现转换器
        pass

converters.py

from streams import Processor

class Uppercase(Processor):
    def converter(self,data):#实现抽象超类的方法
        return data.upper()
class HTMLize:
    def write(self,line):
        print('<UP>{}</UP>'.format(line.rstrip()))
if __name__ == '__main__':
    sep='---------------'
    import sys
    print('查看 tyxt.txt内容:\n{}'.format(open('tyxt.txt').read()))
    print(sep)
    Uppercase(open('tyxt.txt'),sys.stdout).process()
    print()
    print(sep)
    Uppercase(open('tyxt.txt'),open('tyxtup.txt','w')).process()
    print('查看 tyxtup.txt内容:\n{}'.format(open('tyxtup.txt').read()))
    print(sep)
    Uppercase(open('tyxt.txt'),HTMLize()).process()

'''
E:\documents\F盘>python converters.py
查看 tyxt.txt内容:
tyxt.work
bbs.tyxt.work
---------------
TYXT.WORK
BBS.TYXT.WORK
---------------
查看 tyxtup.txt内容:
TYXT.WORK
BBS.TYXT.WORK
---------------
<UP>TYXT.WORK</UP>
<UP>BBS.TYXT.WORK</UP>
'''

1.4 委托:包装对象

用法

在__init__(self,obj)方法中传入被委托对象(obj),并且赋值给包装类的属性。

在__getattr__(self,attrname)方法,拦截被委托对象的点号运算,返回属性。

示例

class MyWrapper:
    def __init__(self,obj):
        #传入被委托对象,赋值给包装类的属性
        self.wrapped=obj
    def __getattr__(self,attrname):
        #拦截点号运算
        print('trace:',attrname)
        #返回被委托对象属性
        return getattr(self.wrapped,attrname)
if __name__ == '__main__':
    mwL=MyWrapper([1,2,3])
    mwL.append('梯阅线条')
    print(mwL.wrapped)
'''E:\documents\F盘>python trace.py
trace: append
[1, 2, 3, '梯阅线条']
'''

http://www.kler.cn/a/144495.html

相关文章:

  • 【数据结构】用C语言实现顺序栈(附完整运行代码)
  • JMeter 设置请求头信息的详细步骤
  • leetcode刷题详解——买卖股票的最佳时机含手续费
  • 25. Spring源码篇之SpEL表达式
  • Python实现一箭穿心
  • Jensen不等式
  • Python基础入门例程75-NP75 使用字典计数(字典)
  • #Js篇:async函数await 命令
  • 2016年11月16日 Go生态洞察:Go字体的创新之旅
  • docker部署MySQL5.7设置密码和远程访问的方法
  • Unity中Shader的Standard材质解析(二)
  • windows版本的grafana如何离线安装插件
  • C语言SO EASY(ZZULIOJ1220: SO EASY)
  • Python编程技巧 – Lambda函数
  • 微信小程序实现类似Vue中的computed、watch功能
  • 面向电力系统的多路实时数据采集通道设计
  • 最新yolov8环境搭建、推理训练一站式超详细教学
  • Vue3进阶5个小知识点 附带源码
  • jpom学习
  • Linux的基本指令(二)