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

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

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

  披萨店团队可以通过文件。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>

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

python3--类与继承和组合的更多相关文章

  1. Python3 类和继承和组合

    import random as r class Fish: def __init__(self): self.x = r.randint(0,10) self.y = r.randint(0,10) ...

  2. python3 面向对象、类、继承、组合、派生、接口、子类重用父类方法

    对象是特征(变量)与技能(函数)的结合体而类是一系列对象共同的特征与技能的集合体 class teacher: lesson = "python" def __init__(sel ...

  3. Day 23 类的继承,派生,组合,菱形继承,多态与多态性

    类的继承 继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类 继承的特性是:子类会遗传父类的属性 继承是类与类之间的关系 为什么用继承 使用继承可以减少代码的冗余 对象的继承 python中 ...

  4. Python3 类的继承

    目录 继承的基本概念 什么是继承 继承有什么用 如何实现继承 初识继承 寻找继承关系 如何寻找继承关系 实例演示 继承背景下的对象属性查找顺序 派生 新式类和经典类 钻石继承 通过继承实现修改json ...

  5. Python3 类的继承小练习

    1.打印并解释结果 class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print(Pa ...

  6. Python基础(16)_面向对象程序设计(类、继承、派生、组合、接口)

    一.面向过程程序设计与面向对象程序设计 面向过程的程序设计:核心是过程,过程就解决问题的步骤,基于该思想设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题的简单化,流程化 缺点: ...

  7. Python3 面向对象-类的继承与派生

    1.什么是继承? 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类可称为基类或超类,新建的类称为派生类和或子类. 子类会遗传父类的属性,从而解决代码重用问题. ...

  8. Day 18 :面向对象[基础,继承,组合]类的增删改查

    有的人说,编程有3种范式: 1.面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了. 2.面向函数:面向函数是面向过程的升级版,也就是把每个 ...

  9. python3 入门 (四) 类与继承

    Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. p ...

  10. Inheritance, Association, Aggregation, and Composition 类的继承,关联,聚合和组合的区别

    在C++中,类与类之间的关系大概有四种,分别为继承,关联,聚合,和组合.其中继承我们大家应该都比较熟悉,因为是C++的三大特性继承Inheritance,封装Encapsulation,和多态Poly ...

随机推荐

  1. 如何快速构建CMBD系统-glpi

    一.CMBD系统构建步骤 起初,开发这套CMBD系统是为了帮助朋友公司简化设备统计操作,以代替人工入库方式.举个例子,单位发放笔记本,或者设备更换了硬盘,都需要人工签到,手动输入统计,安装了CMBD系 ...

  2. mysqldatadir 转移

    当mysql data路径与原始目录不一致时 ,请在mysql 安装目录下my-default.ini 进行设置,取消对应#注释的地址,设置新地址,保存,重新启动,即可. 从网上各种搜索啊,各种尝试, ...

  3. Outlook 2016 自动发送/接收无法正常工作

    如果您的自动/发送接收由于某种原因停止工作,可能会非常令人沮丧,因为您必须记住手动执行发送/接收(F9).如果您遇到Outlook无法自动发送或接收电子邮件的问题,可以尝试以下几项操作. #1 发送/ ...

  4. HDU Rabbit and Grass 兔子和草 (Nim博弈)

    思路:简单Nim博弈,只需要将所给的数字全部进行异或,结果为0,则先手必败.否则必胜. #include <iostream> using namespace std; int main( ...

  5. 洛谷 P2966 [USACO09DEC]牛收费路径Cow Toll Paths

    题目描述 Like everyone else, FJ is always thinking up ways to increase his revenue. To this end, he has ...

  6. 剑指offer64 数据流中的中位数

    priority_queue优先级队列,他的模板声明带有三个参数,priority_queue<Type, Container, Functional> Type 为数据类型, Conta ...

  7. Java 从资源文件(.properties)中读取数据

    在Java工程目录src下,创建一个后缀为.properties的文件,例如db.properties 文件中的内容如下(键=值): name=mk age=123 address=China 在程序 ...

  8. javaweb基础(9)_Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  9. cocostudio的bug(1)

    今天有个女同事问我一个问题,两个cocostudio的ui同时addChild到一个layer上面,高层级的ui设置visible为false,低层级的ui设置的visible设置为true,然后低层 ...

  10. MFC 菜单编程 -- 总结

    菜单结构 一个菜单栏可以有若干个子菜单,而一个子菜单又可有若干个菜单项.对于菜单栏的子菜单,由左至右从0开始索引.对于特定的子菜单的菜单项,由上至下建立从0开始的索引.访问子菜单和菜单项,均可通过其索 ...