类与对象-组合

  1. 计算有多少个实例化对象调用了一个类
class A:

    count = 0 def __init__(self): A.count += 1 a1 = A() a2 = A() print(A.count) # 2

2. 组合就是将一个对象封装到另一个对象的属性中

class Game_role:

    def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, obj2): print("%s攻击了%s, %s掉了%s血,还剩%s血" % (self.name, obj2.name, obj2.name, self.ad, obj2.hp-self.ad)) class Weapen: def __init__(self, name, ad): self.name = name self.ad = ad def weapen_attack(self, p1, p2): # 这里表示会受到人和武器的双重伤害 p2.hp -= self.ad + p1.ad print("%s利用%s攻击了%s%s还剩%s血" % (p1.name, self.name, p2.name, p2.name, p2.hp)) # 实例化两个游戏角色对象 p1 = Game_role("盖伦", 10, 100) p2 = Game_role("剑豪", 20, 80) # 实例化一个武器对象 pillow = Weapen("枕头", 2) pillow.weapen_attack(p1, p2) # 运行结果: 盖伦利用枕头攻击了剑豪,剑豪还剩68

3. 上面的示例中有个奇怪的地方,就是实例化一个武器对象 pillow 后,它调用了 weapen_attack() 方法,也就是这个武器作为发起者。按照正常逻辑来说,应该是人发起攻击才合理

class Game_role:

    def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self, obj2): print("%s攻击了%s, %s掉了%s血,还剩%s血" % (self.name, obj2.name, obj2.name, self.ad, obj2.hp-self.ad)) def equip_weapen(self, w): # 给对象封装一个属性,该属性是另一个类的对象 self.w = w class Weapen: def __init__(self, name, ad): self.name = name self.ad = ad def weapen_attack(self, p1, p2): p2.hp -= self.ad + p1.ad print("%s利用%s攻击了%s%s还剩%s血" % (p1.name, self.name, p2.name, p2.name, p2.hp)) p1 = Game_role("盖伦", 10, 100) p2 = Game_role("剑豪", 20, 80) pillow = Weapen("枕头", 2) print(p1.__dict__) # 运行结果: {'name': '盖伦', 'ad': 10, 'hp': 100} # 这里是重点,pillow 是另一个类 Weapen 的实例化对象 # 此时类 Game_role 的一个实例化对象 p1 调用类的方法 equip_weapon 时 # pillow 作为参数传进去,相当于是一个人 p1 "装备了" pillow "这个武器" # 也就是说,p1 这个实例化对象多了一个属性 pillow p1.equip_weapen(pillow) print(p1.__dict__) # 运行结果: {'name': '盖伦', 'ad': 10, 'hp': 100, 'w': <__main__.Weapen object at 0x7fa8ca1265f8>} # 根据上面的字典可知,此时,p1.w 就是指向实例化对象 pillow 在内存中的地址 # 也就是或, p1.w = pillow # 而在上一个示例中,pillow 调用类 Weapen 的方法是这样: # pillow.weapen_attack(p1, p2) # 相当于 p1.w.weapen_attack(p1, p2) p1.w.weapen_attack(p1, p2) # 运行结果: 盖伦利用枕头攻击了剑豪,剑豪还剩68# 现在看起来就像是 p1 发起的攻击,在逻辑上也更合理了

4. 组合的好处:

  • 使代码的逻辑更合理
  • 就是为了解耦,让程序的各个角色之间相互独立,再增加两个独立的角色之间 的关联性
class User:

    def __init__(self, name): # 每一个用户都有自己名字,所以要放在这里 self.name = name self.order_list = [] class Order: def __init__(self, o_id): self.o_id = o_id self.goods_list = [] class Goods: def __init__(self, name, price): self.name = name self.price = price apple = Goods("苹果", 5) banana = Goods("香蕉", 3) o1 = Order(1) o1.goods_list.append(apple) o1.goods_list.append(banana) print(o1.goods_list) # 运行结果: [<__main__.Goods object at 0x7f03744ef630>, <__main__.Goods object at 0x7f03744ef6a0>] class Order: def __init__(self, o_id): self.o_id = o_id self.goods_list = [] o1 = Order(1) o1.goods_list.append(["苹果", 5]) o1.goods_list.append(["香蕉", 3]) # 如果还有一个对象 o2 o2 = Order(2) o2.goods_list.append(["苹果", 5]) # 如果苹果降价了,变为 4 元,那么 o1、o2 都得一个一个变 # 而在上面的程序中只需改变 apple.price 的值即可 # 所以组合就是让程序的各个角色之间相互独立,再增加两个独立的角色之间的关联性 print(o1.goods_list) # [['苹果', 5], ['香蕉', 3]]

猜你喜欢

转载自www.cnblogs.com/zyqui/p/12454841.html