• python3--类与继承和组合


    类和继承:“是一个”关系

      我们已经深入探索了继承的机制,这里举个例子来说明它是如何用于模拟真实世界的关系的。从程序员的角度来看,继承是由属性点号运算启动的,由此触发实例、类以及任何超类中的变最名搜索。从设计师的角度来看,继承是一种定义集合成员关系的方式:类定义了一组内容属性,可由更具体的集合(子类)继承和定制。

      为了说明,再看前面提到过的制作披萨的机器人的例子。假设我们决定探索另一条路径,开一家披萨餐厅。我们需要做的其中一件事就是聘请员工为顾客服务,准备食物等等。工程师是核心,我们决定创造一个机器人制作披萨,但是,为了让行政和网络关系正确,我们也决定把机器人做成有薪水的功能齐全的员工。

      披萨店团队可以通过文件。mploy。。,.Py中的四个类来定义.最通用的类Employee提供共同行为,例如,加薪(giveRaise)和打印(__repr__).员工有两种,所以Employee有两个子类:Chef和Server。这两个都会覆盖继承的树。rk方法来打印更具体的信息。最后,我们的披萨机器人是由更具体的类来模拟:pizzaRobot是一种chef,也是一种Emp1oyee。以OOP术语来看,我们称这些关系为“是一个”(is一a)链接:机器人是一个主厨,而主厨是一个员工。以下是emPloyoes.Py文件。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    class Employee:
        def __init__(self, name, salary=0):
            self.name = name
            self.salary = salary
        def giveRise(self, percent):
            self.salary = self.salary + (self.salary * percent)
        def work(self):
            print(self.name, "does stuff")
        def __repr__(self):
            return "<Employee: name=%s, salary=%s>" %( self.name, self.salary)
    
    class Chef(Employee):
        def __init__(self, name):
            Employee.__init__(self, name, 50000)
        def work(self):
            print(self.name, "makes food")
    
    class Server(Employee):
        def __init__(self, name):
            Employee.__init__(self, name, 40000)
        def work(self):
            print(self.name, "interfaces with custumer")
    
    class PizzRoboot(Chef):
        def __init__(self, name):
            Chef.__init__(self, name)
        def work(self):
            print(self.name, "makes pizza")
    
    if __name__ == "__main__":
        bob = PizzRoboot("bob")
        print(bob)
        bob.work()
        bob.giveRise(0.20)
        print(bob)
        print("--------------------------")
    
        for klass in Employee, Chef, Server, PizzRoboot:
            obj = klass(klass.__name__)
            obj.work()

    当我们执行此模块中的自我测试代码时,会创建一个名为bob的制作披萨机器人,从三个类继承变量名:pizzaRobot、chef以及Employee。例如,打印匕ob会执行Employee.__repr__方法,而给与bob加薪,则会运行Eoployee.giveRaise,因为会在这里继承找到这个方法。

    <Employee: name=bob, salary=50000>
    bob makes pizza
    <Employee: name=bob, salary=60000.0>
    --------------------------
    Employee does stuff
    Chef makes food
    Server interfaces with custumer
    PizzRoboot makes pizza

    当我们执行此模块中的自我测试代码时,会创建一个名为bob的制作披萨机器人,从三个类继承变量名:pizzaRobot、chef以及Employee。例如,打印bob会执行Employee.__repr__方法,而给与bob加薪,则会运行Employee.giveRaise,因为会在这里继承找到这个方法。

    类和组合:“有一个”关系

    组合的概念.从程序员的角度来看,组合涉及到把其他对象嵌入到容器对象内,并使其实现容器方法。对设计师来说,组合是另一种表示问题领域中的关系的方式。但是,组合不是集合的成员关系,而是组件,也就是整体的组成部分。

    组合也反应了各组成部分之间的关系,通常称为‘有一个”(has一a)关系。有些OOP设计书籍把组合称为聚合(aggregation),或者使用聚合指称容器和所含的物之间较弱的依赖关系,来区分这两个术语。本书中,“组合”就是指内嵌对象集合体。组合类一般都提供自己的接口,并通过内嵌的对象来实现接口。

    现在,我们已经有了员工,把他们放到披萨店,开始忙吧。我们的披萨店是一个组合对象,有个烤炉,也有服务生和主厨这些员工。当顾客来店下单时,店里的组件就会开始行动:服务生接下订单,主厨制作披萨等等。下面的例子(文件pizzashop.py)模拟了这个场景中所有的对象和关系。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    class Employee:
        def __init__(self, name, salary=0):
            self.name = name
            self.salary = salary
        def giveRise(self, percent):
            self.salary = self.salary + (self.salary * percent)
        def work(self):
            print(self.name, "does stuff")
        def __repr__(self):
            return "<Employee: name=%s, salary=%s>" %( self.name, self.salary)
    
    class Chef(Employee):
        def __init__(self, name):
            Employee.__init__(self, name, 50000)
        def work(self):
            print(self.name, "makes food")
    
    class Server(Employee):
        def __init__(self, name):
            Employee.__init__(self, name, 40000)
        def work(self):
            print(self.name, "interfaces with custumer")
    
    class PizzRoboot(Chef):
        def __init__(self, name):
            Chef.__init__(self, name)
        def work(self):
            print(self.name, "makes pizza")
    
    class Customer:
        def __init__(self, name):
            self.name = name
        def order(self, server):
            print(self.name, "orders from", server)
        def pay(self, server):
            print(self.name, "pays for item to", server)
    
    class Oven:
        def bake(self):
            print("oven bakes")
    
    class PizzaShop:
        def __init__(self):
            self.server = Server("Pat")
            self.chef = PizzRoboot("Bob")
            self.oven = Oven()
        def order(self, name):
            customer = Customer(name)
            customer.order(self.server)
            self.chef.work()
            self.oven.bake()
            customer.pay(self.server)
    
    if __name__ == "__main__":
        scene = PizzaShop()
        scene.order("Homer")
        print("...")
        scene.order("Shaggy")
    

      pizzashop类是容器和控制器,其构造器会创建上一节所编写的员工类实例并将其嵌入.此外,。ven类也是在这里定义的。当此模块的自我测试程序代码调用pozzashoporder方法时,内嵌对象会按照顺序进行工作.注意:每份订单创建了新的Customer对象,而且把内嵌的server对象传给Customer方法。顾客是流动的,但是,服务生是披萨店的组合成分。另外,员工也涉及了继承关系,组合和继承是互补的工具。当执行这个模块时,我们的披萨店处理了两份订单:一份来自Homer,另一份来自Shaggy。

    Homer orders from <Employee: name=Pat, salary=40000>
    Bob makes pizza
    oven bakes
    Homer pays for item to <Employee: name=Pat, salary=40000>
    ...
    Shaggy orders from <Employee: name=Pat, salary=40000>
    Bob makes pizza
    oven bakes
    Shaggy pays for item to <Employee: name=Pat, salary=40000>

    同样地,这只是一个用来模拟的例子,但是,对象和交互足以代表组合的工作.其简明的原则就是,类可以表示任何用一句话表达的对象和关系。只要用类取代名词,用方法取代动词,就有第一手的设计方案了。

  • 相关阅读:
    ExtJS5入门
    时间序列异常检测
    RNN实例
    数据清洗入门
    异常检测LOF
    sklearn异常检测demo
    孤立森林(Isolation Forest)
    WCF初见之SQL数据库的增删改查
    NHibernate与EF(Entity Framework)的区别
    解决IIS7虚拟目录出现HTTP 错误 500.19(由于权限不足而无法读取配置文件)的问题
  • 原文地址:https://www.cnblogs.com/chenlin163/p/7307962.html
Copyright © 2020-2023  润新知