4. 面向对象编程:类与对象、继承与多态、特殊方法、设计模式初探
好,咱们进入第四讲。面向对象编程,简称 OOP。说实话,这个概念在风电系统里太重要了。你想想看,一个风电场有成百上千台风机,每台风机都有风速、功率、温度这些属性,还有启动、停机、偏航这些动作。这不就是天然的「对象」吗?
我个人习惯,讲 OOP 从来不讲那些「动物叫」的例子。咱们直接拿风机说事,这样你学完就能用。
4.1 类与对象:从蓝图到实体
先搞清楚两个概念:类是蓝图,对象是实体。
就好比说,我们有一张风机设计图纸,这叫「类」。按照这张图纸造出来的每一台风机,就叫「对象」。每台风机都有自己的序列号、安装位置、当前发电量,但这些风机都能做同样的事情——发电、偏航、变桨。
来看代码:
class WindTurbine:
"""风机类"""
def __init__(self, turbine_id, location, rated_power):
self.turbine_id = turbine_id # 风机编号
self.location = location # 安装位置
self.rated_power = rated_power # 额定功率
self.current_power = 0.0 # 当前功率
self.status = 'stopped' # 运行状态
def start(self):
self.status = 'running'
print(f'{self.turbine_id} 已启动')
def stop(self):
self.status = 'stopped'
self.current_power = 0.0
print(f'{self.turbine_id} 已停机')
# 创建两个风机对象
wt1 = WindTurbine('WT-001', 'A区3号', 2000)
wt2 = WindTurbine('WT-002', 'B区7号', 2000)
wt1.start() # 输出: WT-001 已启动
我在项目中遇到过一个问题:有人把风机编号写成了数字类型,结果后面做字符串拼接时老是报错。嗯,这里要注意,__init__ 方法里的属性类型最好一开始就定好,省得后面踩坑。
4.2 继承与多态:复用与扩展
继承,说白了就是「儿子继承老子的家产」。在风电系统里,我们有各种类型的风机:陆上风机、海上风机、直驱风机、双馈风机。它们有很多共同点,但又有各自的特点。
这时候继承就派上用场了:
class OffshoreTurbine(WindTurbine):
"""海上风机,继承自 WindTurbine"""
def __init__(self, turbine_id, location, rated_power, water_depth):
super().__init__(turbine_id, location, rated_power)
self.water_depth = water_depth # 水深
self.corrosion_level = 'high' # 腐蚀等级
def start(self):
# 多态:重写父类的 start 方法
self._check_sea_condition()
super().start()
def _check_sea_condition(self):
print(f'检查海况,当前水深 {self.water_depth} 米')
# 多态演示
turbines = [
WindTurbine('WT-001', 'A区', 2000),
OffshoreTurbine('WT-101', '海上C区', 5000, 25)
]
for t in turbines:
t.start() # 同一个方法名,不同行为
多态是什么意思?就是「同一个接口,不同实现」。你看上面的 start() 方法,陆上风机直接启动,海上风机要先检查海况再启动。调用者不用关心具体实现,这就是多态的魅力。
我曾经在做一个风场聚合系统时,就是因为用了多态,新增一种风机类型只需要写一个子类,主程序一行代码都不用改。那感觉,真爽。
4.3 特殊方法:让对象更「Pythonic」
Python 里有很多以双下划线开头和结尾的方法,叫特殊方法,也叫魔术方法。它们让我们的对象能像原生类型一样好用。
举个例子,你想让两台风机做比较,或者打印风机信息时更直观:
class WindTurbine:
def __init__(self, turbine_id, power):
self.turbine_id = turbine_id
self.power = power
def __str__(self):
"""打印时显示友好信息"""
return f'风机 {self.turbine_id} (当前功率: {self.power}kW)'
def __repr__(self):
"""调试时显示详细信息"""
return f'WindTurbine({self.turbine_id!r}, {self.power})'
def __lt__(self, other):
"""支持小于比较,用于排序"""
return self.power < other.power
def __add__(self, other):
"""支持加法,合并功率"""
return self.power + other.power
wt1 = WindTurbine('WT-001', 1500)
wt2 = WindTurbine('WT-002', 1800)
print(wt1) # 输出: 风机 WT-001 (当前功率: 1500kW)
print(wt1 < wt2) # 输出: True
print(wt1 + wt2) # 输出: 3300
你看,定义了 __str__ 后,直接 print(wt1) 就能看到有意义的信息,而不是 <__main__.WindTurbine object at 0x...>。定义了 __lt__ 后,就能直接用 sorted() 对风机列表按功率排序了。
我个人习惯,每个类至少实现 __str__ 和 __repr__,调试时能省一半时间。
4.4 设计模式初探:站在巨人的肩膀上
设计模式,说白了就是「前人总结的套路」。你想想看,风电系统里有很多重复出现的问题:怎么创建不同类型的风机?怎么监控风机状态变化?怎么通知多个子系统?这些问题都有现成的解决方案。
咱们先看两个最常用的:
4.4.1 工厂模式:批量生产风机
class TurbineFactory:
"""风机工厂"""
@staticmethod
def create_turbine(turbine_type, **kwargs):
if turbine_type == 'onshore':
return WindTurbine(**kwargs)
elif turbine_type == 'offshore':
return OffshoreTurbine(**kwargs)
elif turbine_type == 'direct_drive':
return DirectDriveTurbine(**kwargs)
else:
raise ValueError(f'未知风机类型: {turbine_type}')
# 使用工厂
wt = TurbineFactory.create_turbine(
'offshore',
turbine_id='WT-101',
location='海上C区',
rated_power=5000,
water_depth=25
)
工厂模式的好处是:创建对象的逻辑集中在一处,新增风机类型时只改工厂类,调用方不用动。我在做风场配置系统时就用这个模式,支持了十几种风机型号的配置。
4.4.2 观察者模式:风场监控系统
class AlarmSystem:
"""报警系统,观察者"""
def update(self, turbine_id, status):
if status == 'fault':
print(f'【报警】风机 {turbine_id} 发生故障!')
class DataLogger:
"""数据记录器,观察者"""
def update(self, turbine_id, status):
print(f'记录: {turbine_id} 状态变为 {status}')
class WindTurbine:
def __init__(self, turbine_id):
self.turbine_id = turbine_id
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def set_status(self, new_status):
self.status = new_status
self._notify_observers()
def _notify_observers(self):
for obs in self._observers:
obs.update(self.turbine_id, self.status)
# 使用
wt = WindTurbine('WT-001')
wt.add_observer(AlarmSystem())
wt.add_observer(DataLogger())
wt.set_status('fault') # 自动通知所有观察者
观察者模式在风电监控系统里太常见了。一台风机状态变化,要通知报警系统、数据记录系统、SCADA 系统、运维调度系统……用观察者模式,耦合度低,扩展性好。
知识体系总览
下面这张图,把本章的核心逻辑串起来了:
这张图展示了 OOP 四大核心在风电系统中的位置。从上往下看:先理解类与对象这个基础,然后用继承和多态做扩展,用特殊方法让代码更优雅,最后用设计模式解决复杂问题。
好了,这一章就到这里。记住:面向对象不是语法,是一种思维方式。你写代码时多想想「这个风机有什么属性?能做什么动作?和其他风机有什么关系?」——想清楚了,代码自然就写好了。