Python 复合设计是指通过组合现有对象来实现新的功能,这在面向对象编程中是一个非常实用的技巧。以下是 Python 复合设计的使用方法:
实现复合设计的方式
Python 实现复合设计的方式有两种:
- 组合:将一个对象作为另一个对象的属性,用于表示整体和部分之间的关系。
- 委托:在一个对象中定义一个方法,并将其调用委托给另一个对象。
组合方式
组合方式通常用于表示整体和部分之间的关系,其中整体对象拥有一个或多个部件对象。下面是一个例子:
class Car:
def __init__(self, engine, tires):
self._engine = engine
self._tires = tires
def description(self):
return f"I'm a car with a {self._engine} engine and {self._tires} tires."
class Engine:
def __init__(self, cylinders):
self.cylinders = cylinders
def description(self):
return f"I'm an engine with {self.cylinders} cylinders."
class Tires:
def __init__(self, type):
self.type = type
def description(self):
return f"I'm a tire of type {self.type}."
在这个例子中,整体对象 Car
有一个引擎 Engine
和一组轮胎 Tires
。 Engine
和 Tires
的 description
方法将被整体对象 Car
的 description
方法调用。
委托方式
委托方式通常用于继承方式不可行或不可取的情况下,可以将基类中的代码与新的功能实现组合起来。下面是一个例子:
class Base:
def method(self):
pass
class Derived:
def __init__(self, base):
self._base = base
def method(self):
# 委托给_base对象
self._base.method()
# 在此添加新的功能
在这个例子中, Derived
类在其 method
方法中将调用基类 Base
的 method
方法,并在其之后加入新的功能。
示例说明
现在假设我们需要为所有的手机添加一个播放音乐的功能,但是我们不希望在每个手机中都重复实现这个功能,我们可以选择使用 Python 复合设计来完成。
class Phone:
def __init__(self, screen, battery):
self._screen = screen
self._battery = battery
def play_music(self):
print("Playing music...")
class Screen:
def __init__(self, size):
self.size = size
class Battery:
def __init__(self, capacity):
self.capacity = capacity
在这个例子中,我们定义了 Phone
类表示一款手机,具有屏幕和电池等组件。我们在 Phone
类中添加了一个 play_music
方法用于播放音乐。现在我们可以通过实例化一个 Phone
对象来使用 play_music
方法。
screen = Screen(5)
battery = Battery(4000)
phone = Phone(screen, battery)
phone.play_music()
输出为 Playing music...
。
另一个示例是,我们假设我们需要实现一个类来表示一个可以开车的人,但是我们不希望在每个对象中都实现驾驶方法。我们可以编写一个 Driver
类并将其组合到 Person
类中。
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
self._driver = None
def assign_driver(self, driver):
self._driver = driver
def drive(self):
if self._driver is None:
print(f"{self._name} doesn't know how to drive.")
else:
self._driver.drive()
class Driver:
def __init__(self, name):
self.name = name
def drive(self):
print(f"{self.name} is driving.")
在这个例子中,我们定义了 Person
类表示一个人,并具有一个 assign_driver
方法用于将驾驶员对象分配给此人。我们也定义了一个 Driver
类来表示驾驶员。我们在 Person
类中添加了一个 drive
方法,并在其中委托 Driver
对象来驾驶。
driver = Driver("John")
person = Person("Alice", 25)
person.assign_driver(driver)
person.drive()
输出为 John is driving.
。
通过组合和委托的方式,我们可以实现更加灵活的代码设计和更好的代码重用。