面向对象组合用法
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另一个类的对象作为数据属性,称为类的组合
1 class Arms: # 定义武器类 2 bullet = 7.62 3 def hit(self,man): # 装备功能 4 pass 5 class Man: # 定义一个男人 6 role = 'person' 7 def __init__(self,name,arms): 8 self.name = name # 人的名字 9 self.arms = Arms() # 给人添加一个武器 10 human = Man('exes','ak117') 11 human.arms.hit('exes') 12 # human组合了一个武器的对象,可以直接human.arms来使用组合类中的所有方法
圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用
1 from math import pi 2 3 class Circle: 4 ''' 5 定义了一个圆形类; 6 提供计算面积(area)和周长(perimeter)的方法 7 ''' 8 def __init__(self,radius): 9 self.radius = radius 10 11 def area(self): 12 return pi * self.radius * self.radius 13 14 def perimeter(self): 15 return 2 * pi *self.radius 16 17 18 circle = Circle(10) #实例化一个圆 19 area1 = circle.area() #计算圆面积 20 per1 = circle.perimeter() #计算圆周长 21 print(area1,per1) #打印圆面积和周长 22 23 class Ring: 24 ''' 25 定义了一个圆环类 26 提供圆环的面积和周长的方法 27 ''' 28 def __init__(self,radius_outside,radius_inside): 29 self.outsid_circle = Circle(radius_outside) 30 self.inside_circle = Circle(radius_inside) 31 32 def area(self): 33 return self.outsid_circle.area() - self.inside_circle.area() 34 35 def perimeter(self): 36 return self.outsid_circle.perimeter() + self.inside_circle.perimeter() 37 38 39 ring = Ring(10,5) #实例化一个环形 40 print(ring.perimeter()) #计算环形的周长 41 print(ring.area()) #计算环形的面积
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
小练习:
人狗大战
class Person: # 定义一个人类 role = 'person' # 人的角色属性都是人 def __init__(self, name, aggressivity, life_value, money): self.name = name # 每一个角色都有自己的昵称; self.aggressivity = aggressivity # 每一个角色都有自己的攻击力; self.life_value = life_value # 每一个角色都有自己的生命值; self.money = money def attack(self,dog): # 人可以攻击狗,这里的狗也是一个对象。 # 人攻击狗,那么狗的生命值就会根据人的攻击力而下降 dog.life_value -= self.aggressivity class Dog: # 定义一个狗类 role = 'dog' # 狗的角色属性都是狗 def __init__(self, name, breed, aggressivity, life_value): self.name = name # 每一只狗都有自己的昵称; self.breed = breed # 每一只狗都有自己的品种; self.aggressivity = aggressivity # 每一只狗都有自己的攻击力; self.life_value = life_value # 每一只狗都有自己的生命值; def bite(self,people): # 狗可以咬人,这里的狗也是一个对象。 # 狗咬人,那么人的生命值就会根据狗的攻击力而下降 people.life_value -= self.aggressivity class Weapon: def __init__(self,name, price, aggrev, life_value): self.name = name self.price = price self.aggrev = aggrev self.life_value = life_value def update(self, obj): #obj就是要带这个装备的人 obj.money -= self.price # 用这个武器的人花钱买所以对应的钱要减少 obj.aggressivity += self.aggrev # 带上这个装备可以让人增加攻击 obj.life_value += self.life_value # 带上这个装备可以让人增加生命值 def prick(self, obj): # 这是该装备的主动技能,扎死对方 obj.life_value -= 500 # 假设攻击力是500 lance = Weapon('长矛',200,6,100) egg = Person('egon',10,1000,600) #创造了一个实实在在的人egg ha2 = Dog('二愣子','哈士奇',10,1000) #创造了一只实实在在的狗ha2 #egg独自力战"二愣子"深感吃力,决定穷毕生积蓄买一把武器 if egg.money > lance.price: #如果egg的钱比装备的价格多,可以买一把长矛 lance.update(egg) #egg花钱买了一个长矛防身,且自身属性得到了提高 egg.weapon = lance #egg装备上了长矛 print(egg.money,egg.life_value,egg.aggressivity) print(ha2.life_value) egg.attack(ha2) #egg打了ha2一下 print(ha2.life_value) egg.weapon.prick(ha2) #发动武器技能 print(ha2.life_value) #ha2不敌狡猾的人类用武器取胜,血槽空了一半