本文结合工控场景讲解 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)
    }
}

总结

  1. :工控场景中对应设备 / 通信的 “模板”,定义设备的属性(参数)和行为(操作),类比 PLC 功能块;
  2. 封装:隐藏设备 / 通信的内部细节,只暴露安全的操作接口,防止参数非法赋值(如转速超限);
  3. 继承:复用同类设备 / 通信的通用逻辑(如所有设备都有启停,所有通信都有连接断开),只扩展特有功能;
  4. 多态:同一操作(如启动、读取寄存器)对不同设备 / 通信方式有不同实现,适配工控场景的设备多样性;
  5. 工业类设计核心:设备类聚焦 “属性 + 操作”,通信类聚焦 “连接 + 读写”,通过面向对象特性实现代码复用和扩展。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐