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

本文介绍了Python中通过继承、组合和委托组织类的方式,包括了继承的is-a关系、组合的has-a关系以及委托的包装对象应用,通过实例展示了如何创建和使用这些类结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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, '梯阅线条']
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值