python和OOP
首先复习一下——python的OOP实现可以总结为三大思想:
- 继承
继承以python中的属性查找的基础; - 多态
在X.method中,method的意义取决于主体对象X的类型(类); - 封装
方法和运算符实现行为,不过默认情况下数据隐藏是一种惯例;
多态意味着接口,不是函数调用的签名
class C():
def meth(self, x):
...
def meth(self, x, y, z)
...
这段代码会运行,但是因为def直接吧对象赋值给类作用域中的变量名,所以方法函数的最后一次定义才是被唯一保留的。
OOP和继承:‘is-a’关系
从程序员的角度看,继承是由属性点号操作启动的,并由此触发实例、类以及任何父类中的变量名搜索;
从类的设计者的角度来看,继承是一种指明集合成员关系的方式,类定义了一个属性集合,可由更具体的集合继承和定制;
class Employees:
def __init__(self, name, salary=0):
self.name = name
self.salary = salary
def giveRaise(self, percent):
self.salary = self.salary + (self.salary * percent)
def work(self):
print(self.name, 'dose stuff')
def __repr__(self):
return '<Employee:name=%s,salary=%s>' %(self.name, self.salary)
class Chef(Employees):
def __init__(self, name):
Employees.__init__(self, name, 50000)
def work(self):
print(self.name, 'makes food')
class Server(Employees):
def __init__(self, name):
Employees.__init__(self, name, 40000)
def work(self):
print(self.name, 'interfaces with customer')
class PizzaRobot(Chef):
def __init__(self, name):
Chef.__init__(self, name)
def work(self):
print(self.name, 'makes pizza')
if __name__ == '__main__':
bob = PizzaRobot('bob')
print(bob) # output:<Employee:name=bob,salary=50000>
bob.work() # output:bob makes pizza
bob.giveRaise(0.02)
print(bob) # output:<Employee:name=bob,salary=51000.0>
for kclass in (Employees, Chef, Server, PizzaRobot):
obj = kclass(kclass.__name__)
obj.work() # output:Employees dose stuff
# Chef makes food
# Server interfaces with customer
# PizzaRobot makes pizza
OOP和组合:“has-a”关系
从程序员的角度看,组合涉及把其他对象嵌入容器对象内,并促使其实现容器方法。对类的设计者来看,组合是在一个问题领域中另一种呈现关系的方式。但是,组合不是集合的成员关系,而是组件,也就是整体的组成部分。
组合也反映了各组合成分之间的关系,通常称为‘has-a’关系。有时也称为聚合。
上面我们以及创建了各个角色,现在我们需要将这些角色组合成一个pizza店了;
class Employees:
def __init__(self, name, salary=0):
self.name = name
self.salary = salary
def giveRaise(self, percent):
self.salary = self.salary + (self.salary * percent)
def work(self):
print(self.name, 'dose stuff')
def __repr__(self):
return '<Employee:name=%s,salary=%s>' %(self.name, self.salary)
class Chef(Employees):
def __init__(self, name):
Employees.__init__(self, name, 50000)
def work(self):
print(self.name, 'makes food')
class Server(Employees):
def __init__(self, name):
Employees.__init__(self, name, 40000)
def work(self):
print(self.name, 'interfaces with customer')
class PizzaRobot(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 = PizzaRobot('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__':
scane = PizzaShop()
scane.order('Homer')
print('.....')
scane.order('Shaggy')
# output:
# 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>
重访流处理器
我们编写的一段通用数据流处理器函数的代码:
def processor(resder, converter, writer):
while Ture:
data =reader,read()
if not data: break
data = converter(data)
writer.write(data)
OOP和委托:“包装器”代理对象
从某种意义上讲,委托是组合的一种特殊形式。它使用包装器类管理单一的内嵌对象,而包装器类则保留了内嵌对象的大多数或全部的接口。