抽象超类Animal

python
from abc import ABC, abstractmethod
# 方式一
# class Animal:
#
# def make_sound(self):
# raise NotImplementedError('子类必须实现make_sound方法')
# 方式二
class Animal(ABC):
"""抽象类"""
@abstractmethod
def make_sound(self):
"""子类必须实现该方法,表示所有动物都能发出声音"""
pass
class Dog(Animal):
def make_sound(self):
self._bark()
def _bark(self): # 单下划线表示仅内部调用,相当于java的private
print("汪汪叫")
class Cat(Animal):
def make_sound(self):
self._meow()
def _meow(self):
print("喵喵叫")
if __name__ == '__main__':
dog = Dog()
dog.make_sound()
cat = Cat()
cat.make_sound()
实现鸭子的行为

python
from abc import ABC, abstractmethod
class FlyBehavior:
def fly(self):
raise NotImplementedError
class FlyWithWings(FlyBehavior):
def fly(self):
print("鸭子飞行")
class FlyNoWay(FlyBehavior):
def fly(self):
print('不会飞')
class QuackBehavior(ABC):
@abstractmethod
def quack(self):
pass
class Quack(QuackBehavior):
def quack(self):
print('鸭子呱呱叫')
class Squeak(QuackBehavior):
def quack(self):
print('橡皮鸭子呱呱叫')
class MuteQuack(QuackBehavior):
def quack(self):
print('不会叫')
鸭子类

python
class Duck:
def __init__(self):
self.fly_behavior = None
self.quack_behavior = None
def perform_fly(self):
if self.fly_behavior:
self.fly_behavior.fly()
def perform_quack(self):
if self.quack_behavior:
self.quack_behavior.quack()
def swim(self):
pass
@abstractmethod
def display(self):
pass
整合鸭子的行为

python
class MallardDuck(Duck):
def __init__(self):
super().__init__()
self.fly_behavior = FlyWithWings()
self.quack_behavior = Quack()
def display(self):
print("I'm a real Mallard Duck")
测试Duck

python
if __name__ == '__main__':
mallard = MallardDuck()
mallard.perform_quack()
mallard.perform_fly()
动态设定行为

python
class Duck:
...
def set_fly_behavior(self, fly_behavior: FlyBehavior):
self.fly_behavior = fly_behavior
def set_quack_behavior(self, quack_behavior: QuackBehavior):
self.quack_behavior = quack_behavior
class ModelDuck(Duck):
def __init__(self):
super().__init__()
self.fly_behavior = FlyNoWay()
self.quack_behavior = Quack()
def display(self):
print("I'm a model duck")
class FlyRocketPowered(FlyBehavior):
"""利用火箭动力的飞行行为"""
def fly(self):
print("I'm flying with a rocket!")
if __name__ == '__main__':
model = ModelDuck()
model.perform_fly()
model.set_fly_behavior(FlyRocketPowered())
model.perform_fly()
或者换一种方式设置属性,效果一样
python
class Duck:
def __init__(self):
self._fly_behavior = None
self._quack_behavior = None
...
@property
def fly_behavior(self):
return self._fly_behavior
@fly_behavior.setter
def fly_behavior(self, fly_behavior: FlyBehavior):
self._fly_behavior = fly_behavior
@property
def quack_behavior(self):
return self._quack_behavior
@quack_behavior.setter
def quack_behavior(self, quack_behavior: QuackBehavior):
self._quack_behavior = quack_behavior
if __name__ == '__main__':
model = ModelDuck()
model.perform_fly()
model.fly_behavior = FlyRocketPowered()
# model.set_fly_behavior(FlyRocketPowered())
model.perform_fly()
完整代码
python
from abc import ABC, abstractmethod
from typing import Optional
class FlyBehavior:
"""飞行行为"""
def fly(self):
raise NotImplementedError
class FlyWithWings(FlyBehavior):
"""用翅膀飞行"""
def fly(self):
print("I'm flying!!")
class FlyNoWay(FlyBehavior):
"""不支持飞行"""
def fly(self):
print("I can't fly")
class QuackBehavior(ABC):
"""发出声音行为"""
@abstractmethod
def quack(self):
pass
class Quack(QuackBehavior):
def quack(self):
print('鸭子呱呱叫')
class Squeak(QuackBehavior):
def quack(self):
print('橡皮鸭子呱呱叫')
class MuteQuack(QuackBehavior):
def quack(self):
print('不会叫')
class Duck:
def __init__(self,
fly_behavior: Optional[FlyBehavior] = None,
quack_behavior: Optional[QuackBehavior] = None
):
self._fly_behavior = fly_behavior
self._quack_behavior = quack_behavior
def perform_fly(self):
if self.fly_behavior:
self.fly_behavior.fly()
def perform_quack(self):
if self.quack_behavior:
self.quack_behavior.quack()
def swim(self):
pass
@abstractmethod
def display(self):
pass
# def set_fly_behavior(self, fly_behavior: FlyBehavior):
# self.fly_behavior = fly_behavior
#
# def set_quack_behavior(self, quack_behavior: QuackBehavior):
# self.quack_behavior = quack_behavior
@property
def fly_behavior(self):
return self._fly_behavior
@fly_behavior.setter
def fly_behavior(self, fly_behavior: FlyBehavior):
self._fly_behavior = fly_behavior
@property
def quack_behavior(self):
return self._quack_behavior
@quack_behavior.setter
def quack_behavior(self, quack_behavior: QuackBehavior):
self._quack_behavior = quack_behavior
class MallardDuck(Duck): # 继承,属于鸭子 IS-A,是一种鸭子的子类型
def __init__(self):
super().__init__()
self.fly_behavior = FlyWithWings() # 组合,拥有飞行行为 HAS-A
self.quack_behavior = Quack() # 组合,拥有发出声音行为 HAS-A
def display(self):
print("I'm a real Mallard Duck")
class ModelDuck(Duck):
def __init__(self):
super().__init__()
self.fly_behavior = FlyNoWay()
self.quack_behavior = Quack()
def display(self):
print("I'm a model duck")
class FlyRocketPowered(FlyBehavior):
"""利用火箭动力的飞行行为"""
def fly(self):
print("I'm flying with a rocket!")
if __name__ == '__main__':
mallard = MallardDuck()
mallard.perform_quack()
mallard.perform_fly()
model = ModelDuck()
model.perform_fly()
model.fly_behavior = FlyRocketPowered()
# model.set_fly_behavior(FlyRocketPowered())
model.perform_fly()
总结

练习题

python
from abc import abstractmethod
class WeaponBehavior:
"""武器行为"""
@abstractmethod
def use_weapon(self):
"""使用武器"""
pass
class KnifeBehavior(WeaponBehavior):
def use_weapon(self):
return '匕首'
class BowAndArrowBehavior(WeaponBehavior):
def use_weapon(self):
return '弓箭'
class AxeBehavior(WeaponBehavior):
def use_weapon(self):
return '斧头'
class SwordBehavior(WeaponBehavior):
def use_weapon(self):
return '宝剑'
class Character:
"""人物"""
def __init__(self, w: WeaponBehavior = None):
self._weapon = w
@property
def weapon(self):
return self._weapon
@weapon.setter
def weapon(self, w: WeaponBehavior):
self._weapon = w
def fight(self):
"""战斗"""
if self._weapon is None:
print(f"{self.__class__.__name__} has no weapon!")
return
weapon = self._weapon.use_weapon()
print(f"{self.__class__.__name__} use {weapon} fight")
@abstractmethod
def display(self) -> None:
pass
class Queen(Character):
def display(self) -> None:
print("I'm a Queen")
class King(Character):
def display(self) -> None:
print("I'm a King")
class Troll(Character):
def display(self) -> None:
print("I'm a Troll")
class Knight(Character):
def display(self) -> None:
print("I'm a Knight")
if __name__ == '__main__':
queen = Queen()
queen.fight()
queen.weapon = KnifeBehavior()
queen.fight()
king = King(KnifeBehavior())
king.fight()
king.weapon = BowAndArrowBehavior()
king.fight()