C#面向对象核心(类 / 封装 / 继承 / 多态)之工业场景类设计(设备类 / 通信类)
本文结合工控场景讲解 C# 面向对象的核心概念(类 / 封装 / 继承 / 多态),并重点演示工业场景下的类设计(设备类、通信类),我会从工控实际应用出发,把抽象的面向对象概念落地到具体的工业编程场景中。
一、面向对象核心概念(工控视角解读)
先把四大核心概念翻译成工控工程师能理解的语言,再结合代码实现:
|
核心概念 |
工控视角解读 |
类比(工控场景) |
|---|---|---|
|
类(Class) |
设备 / 功能的 “模板”,定义设备有哪些属性(参数)和行为(方法) |
PLC 的功能块(FB)、设备的技术手册(规定了参数和操作) |
|
封装(Encapsulation) |
隐藏设备内部细节,只暴露必要的操作接口,防止误操作 |
设备的操作面板(只给按钮 / 显示屏,内部电路不可见) |
|
继承(Inheritance) |
复用同类设备的通用属性 / 方法,只扩展特有功能 |
所有电机都有转速 / 启停(通用),伺服电机多了定位功能(特有) |
|
多态(Polymorphism) |
同一操作对不同设备有不同实现,适配多样化设备 |
同样是 “启动” 操作,电机启动是转起来,阀门启动是打开 |
二、核心概念实战(工控场景代码实现)
1. 类(Class)—— 定义工业设备模板
核心逻辑:把工业设备的属性(参数)和行为(操作)封装成类,比如 “工业设备基类” 包含所有设备通用的属性(编号、状态)和方法(启停)。
using System;
// 工业设备基类(所有工业设备的通用模板)
public class IndustrialDevice
{
// 通用属性(设备编号、运行状态、累计运行时长)
public string DeviceId { get; set; } // 设备编号
public byte Status { get; set; } // 状态:0=停止,1=运行,2=故障
public int RunHours { get; set; } // 累计运行时长(小时)
// 通用方法(启动、停止)
public virtual void Start() // virtual标记为可被重写(为多态做准备)
{
if (Status == 2)
{
Console.WriteLine($"【{DeviceId}】设备故障,无法启动!");
return;
}
Status = 1;
Console.WriteLine($"【{DeviceId}】设备启动成功!");
}
public virtual void Stop()
{
Status = 0;
Console.WriteLine($"【{DeviceId}】设备停止成功!");
}
// 显示设备状态(通用方法)
public void ShowStatus()
{
string statusDesc = Status switch
{
0 => "停止",
1 => "运行",
2 => "故障",
_ => "未知"
};
Console.WriteLine($"=== 设备【{DeviceId}】状态 ===");
Console.WriteLine($"运行状态:{statusDesc}");
Console.WriteLine($"累计运行时长:{RunHours} 小时");
}
}
2. 封装(Encapsulation)—— 保护设备核心参数
核心逻辑:对关键参数(如电机额定转速)做私有封装,只通过方法 / 属性控制读写,防止非法赋值(比如转速超过额定值)。
// 电机类(继承自工业设备基类,增加封装特性)
public class Motor : IndustrialDevice
{
// 私有核心参数(封装,外部不可直接修改)
private float _ratedSpeed; // 额定转速(r/min)
private float _currentSpeed; // 当前转速
// 公共属性(控制读写权限,加入校验逻辑)
public float RatedSpeed
{
get => _ratedSpeed; // 只读,外部可获取但不可修改
init => _ratedSpeed = value > 0 ? value : throw new ArgumentException("额定转速必须大于0!");
}
public float CurrentSpeed
{
get => _currentSpeed;
set
{
// 封装核心逻辑:转速不能超过额定值,不能为负
if (value < 0)
_currentSpeed = 0;
else if (value > _ratedSpeed)
{
_currentSpeed = _ratedSpeed;
Console.WriteLine($"【{DeviceId}】转速超限,自动降至额定转速{_ratedSpeed}r/min");
}
else
_currentSpeed = value;
}
}
// 构造函数(初始化设备)
public Motor(string deviceId, float ratedSpeed)
{
DeviceId = deviceId;
RatedSpeed = ratedSpeed;
Status = 0; // 初始状态:停止
RunHours = 0;
_currentSpeed = 0;
}
}
3. 继承(Inheritance)—— 复用通用逻辑,扩展特有功能
核心逻辑:不同类型的工业设备(伺服电机、阀门)继承基类的通用属性 / 方法,只扩展自己的特有功能,避免重复代码。
// 伺服电机类(继承电机类,扩展定位功能)
public class ServoMotor : Motor
{
// 特有属性:定位精度、目标位置
public float PositionAccuracy { get; set; } // 定位精度(mm)
public float TargetPosition { get; set; } // 目标位置(mm)
// 特有方法:定位控制
public void MoveToPosition()
{
if (Status != 1)
{
Console.WriteLine($"【{DeviceId}】请先启动伺服电机再执行定位!");
return;
}
Console.WriteLine($"【{DeviceId}】伺服电机定位至{TargetPosition}mm,精度±{PositionAccuracy}mm");
}
// 构造函数(继承父类构造函数)
public ServoMotor(string deviceId, float ratedSpeed, float positionAccuracy)
: base(deviceId, ratedSpeed) // 调用父类构造函数
{
PositionAccuracy = positionAccuracy;
TargetPosition = 0;
}
}
// 阀门类(直接继承工业设备基类,扩展开度控制)
public class Valve : IndustrialDevice
{
// 特有属性:开度(0-100%)
public float Opening { get; set; }
// 特有方法:调节开度
public void AdjustOpening(float targetOpening)
{
if (Status != 1)
{
Console.WriteLine($"【{DeviceId}】请先启动阀门再调节开度!");
return;
}
// 校验开度范围
Opening = targetOpening < 0 ? 0 : (targetOpening > 100 ? 100 : targetOpening);
Console.WriteLine($"【{DeviceId}】阀门开度调节至{Opening}%");
}
public Valve(string deviceId)
{
DeviceId = deviceId;
Status = 0;
RunHours = 0;
Opening = 0;
}
}
4. 多态(Polymorphism)—— 同一操作适配不同设备
核心逻辑:重写基类方法,让 “启动 / 停止” 等通用操作对不同设备有不同实现,比如伺服电机启动时要初始化定位,阀门启动时要复位开度。
// 重写基类的Start方法(多态核心)
public class ServoMotor : Motor
{
// 其他代码不变,新增重写Start方法
public override void Start()
{
if (Status == 2)
{
Console.WriteLine($"【{DeviceId}】伺服电机故障,无法启动!");
return;
}
Status = 1;
// 伺服电机启动特有逻辑:初始化定位
TargetPosition = 0;
CurrentSpeed = RatedSpeed * 0.5f; // 启动时先以50%额定转速运行
Console.WriteLine($"【{DeviceId}】伺服电机启动(初始化定位至0mm,初始转速{CurrentSpeed}r/min)!");
}
}
public class Valve : IndustrialDevice
{
// 其他代码不变,新增重写Start方法
public override void Start()
{
if (Status == 2)
{
Console.WriteLine($"【{DeviceId}】阀门故障,无法启动!");
return;
}
Status = 1;
// 阀门启动特有逻辑:复位开度至0
Opening = 0;
Console.WriteLine($"【{DeviceId}】阀门启动(开度复位至0%)!");
}
}
三、工业场景类设计(设备类 + 通信类)
1. 设备类整合使用(模拟生产线设备控制)
class Program
{
static void Main(string[] args)
{
// 1. 创建伺服电机设备(继承+封装+多态)
var servoMotor = new ServoMotor("M001", 3000, 0.01f);
servoMotor.Start(); // 多态:执行伺服电机特有启动逻辑
servoMotor.TargetPosition = 50.5f;
servoMotor.MoveToPosition(); // 特有方法:定位
servoMotor.ShowStatus(); // 继承基类的通用方法
Console.WriteLine("------------------------");
// 2. 创建阀门设备
var valve = new Valve("V001");
valve.Start(); // 多态:执行阀门特有启动逻辑
valve.AdjustOpening(80); // 特有方法:调节开度
valve.ShowStatus();
// 输出结果:
// 【M001】伺服电机启动(初始化定位至0mm,初始转速1500r/min)!
// 【M001】伺服电机定位至50.5mm,精度±0.01mm
// === 设备【M001】状态 ===
// 运行状态:运行
// 累计运行时长:0 小时
// ------------------------
// 【V001】阀门启动(开度复位至0%)!
// 【V001】阀门开度调节至80%
// === 设备【V001】状态 ===
// 运行状态:运行
// 累计运行时长:0 小时
}
}
2. 通信类设计(工控核心:Modbus 通信类)
工业场景中,通信类是连接上位机和 PLC / 传感器的核心,封装不同通信协议(Modbus TCP/RTU)的通用逻辑,通过多态适配不同通信方式:
// 工业通信基类(封装通用通信逻辑)
public abstract class IndustrialComm
{
// 通用属性
public string IpAddress { get; set; } // IP地址(TCP用)
public int Port { get; set; } // 端口(TCP用)
public string SerialPort { get; set; } // 串口(RTU用)
public bool IsConnected { get; protected set; } // 连接状态
// 抽象方法(必须由子类实现,多态核心)
public abstract bool Connect(); // 连接设备
public abstract bool Disconnect(); // 断开连接
public abstract float ReadRegister(string registerAddr); // 读取寄存器
public abstract bool WriteRegister(string registerAddr, float value); // 写入寄存器
// 通用方法(封装通用逻辑)
public void ShowCommStatus()
{
Console.WriteLine($"通信状态:{(IsConnected ? "已连接" : "未连接")}");
Console.WriteLine($"连接信息:{(string.IsNullOrEmpty(SerialPort) ? $"TCP({IpAddress}:{Port})" : $"RTU({SerialPort})")}");
}
}
// Modbus TCP通信类(继承通信基类,实现TCP特有逻辑)
public class ModbusTcpComm : IndustrialComm
{
public override bool Connect()
{
// 模拟TCP连接逻辑
if (string.IsNullOrEmpty(IpAddress) || Port == 0)
{
Console.WriteLine("TCP连接参数不全!");
return false;
}
IsConnected = true;
Console.WriteLine($"Modbus TCP连接成功:{IpAddress}:{Port}");
return true;
}
public override bool Disconnect()
{
IsConnected = false;
Console.WriteLine("Modbus TCP连接断开");
return true;
}
public override float ReadRegister(string registerAddr)
{
if (!IsConnected)
{
Console.WriteLine("未连接,无法读取寄存器!");
return 0;
}
// 模拟读取PLC寄存器(比如读取温度)
Console.WriteLine($"读取Modbus TCP寄存器{registerAddr}成功");
return 25.5f; // 模拟温度值
}
public override bool WriteRegister(string registerAddr, float value)
{
if (!IsConnected)
{
Console.WriteLine("未连接,无法写入寄存器!");
return false;
}
Console.WriteLine($"向Modbus TCP寄存器{registerAddr}写入值:{value}");
return true;
}
}
// Modbus RTU通信类(继承通信基类,实现RTU特有逻辑)
public class ModbusRtuComm : IndustrialComm
{
public override bool Connect()
{
// 模拟RTU串口连接逻辑
if (string.IsNullOrEmpty(SerialPort))
{
Console.WriteLine("RTU串口参数不全!");
return false;
}
IsConnected = true;
Console.WriteLine($"Modbus RTU连接成功:{SerialPort}");
return true;
}
public override bool Disconnect()
{
IsConnected = false;
Console.WriteLine("Modbus RTU连接断开");
return true;
}
public override float ReadRegister(string registerAddr)
{
if (!IsConnected)
{
Console.WriteLine("未连接,无法读取寄存器!");
return 0;
}
Console.WriteLine($"读取Modbus RTU寄存器{registerAddr}成功");
return 1.2f; // 模拟压力值
}
public override bool WriteRegister(string registerAddr, float value)
{
if (!IsConnected)
{
Console.WriteLine("未连接,无法写入寄存器!");
return false;
}
Console.WriteLine($"向Modbus RTU寄存器{registerAddr}写入值:{value}");
return true;
}
}
// 通信类使用示例
public class CommTest
{
static void Test()
{
// 1. Modbus TCP通信
var tcpComm = new ModbusTcpComm
{
IpAddress = "192.168.1.100",
Port = 502
};
tcpComm.Connect();
float temp = tcpComm.ReadRegister("HR100"); // 读取温度寄存器
Console.WriteLine($"采集温度:{temp}℃");
tcpComm.ShowCommStatus();
Console.WriteLine("------------------------");
// 2. Modbus RTU通信
var rtuComm = new ModbusRtuComm
{
SerialPort = "COM3"
};
rtuComm.Connect();
float pressure = rtuComm.ReadRegister("HR200"); // 读取压力寄存器
Console.WriteLine($"采集压力:{pressure}MPa");
rtuComm.ShowCommStatus();
// 输出结果:
// Modbus TCP连接成功:192.168.1.100:502
// 读取Modbus TCP寄存器HR100成功
// 采集温度:25.5℃
// 通信状态:已连接
// 连接信息:TCP(192.168.1.100:502)
// ------------------------
// Modbus RTU连接成功:COM3
// 读取Modbus RTU寄存器HR200成功
// 采集压力:1.2MPa
// 通信状态:已连接
// 连接信息:RTU(COM3)
}
}
总结
- 类:工控场景中对应设备 / 通信的 “模板”,定义设备的属性(参数)和行为(操作),类比 PLC 功能块;
- 封装:隐藏设备 / 通信的内部细节,只暴露安全的操作接口,防止参数非法赋值(如转速超限);
- 继承:复用同类设备 / 通信的通用逻辑(如所有设备都有启停,所有通信都有连接断开),只扩展特有功能;
- 多态:同一操作(如启动、读取寄存器)对不同设备 / 通信方式有不同实现,适配工控场景的设备多样性;
- 工业类设计核心:设备类聚焦 “属性 + 操作”,通信类聚焦 “连接 + 读写”,通过面向对象特性实现代码复用和扩展。
更多推荐


所有评论(0)