C# 抽象类小谈

最近在做一个测试系统,就是读取功率计上的数据,在上位机软件上显示出来。

电脑界面不是我们这次的主讲就略过,我们这里主要讲一个类的实现。

最开始领导给了一个 远方的三相功率计 给我让我写上位机,很简单,我一会就实现出来了。

由于是三相功率计,所以我们先写个一相的基类出来

public class OnePhase
    {
        public float V { get; set; }
        public float A { get; set; }
        public float W { get; set; }
        public float VA { get; set; }
        public float PF { get; set; }
    }

 

远方的类

 public class PF9830
    {
        public PF9830()
        {
            P1 = new OnePhase();
            P2 = new OnePhase();
            P3 = new OnePhase();
            P4 = new OnePhase();
        }

        public OnePhase P1 { get; set; }
        public OnePhase P2 { get; set; }
        public OnePhase P3 { get; set; }
        public OnePhase P4 { get; set; }

        public void GetValues(byte[] data)
        {
            /*
             * 串口读取值的解释
             * 
             * P1.V = ……
             */
        }
    }

实现类

class Test
    {
        public Test()
        {
            PowerMeter = new PF9830();

            Port = new SerialPort();
            Port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);
        }        

        public PF9830 PowerMeter { get; set; }

        public SerialPort Port { get; set; }

        void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int length = Port.BytesToRead;
            byte[] data = new byte[length];
            Port.Read(data, 0, length);
            PowerMeter.GetValues(data);
        }
    }

工作很快就完成了,也正常运行。可是有一天,领导说远方的测试精度太差了,要换一个横河的功率计进行测试,最好有一个下拉列表,可以选择是哪个仪器。
我刚开始的时候直接再写一个横河的类出来,如下:

public class WT230
    {
        public WT230()
        {
            P1 = new OnePhase();
            P2 = new OnePhase();
            P3 = new OnePhase();
            P4 = new OnePhase();
        }

        public OnePhase P1 { get; set; }
        public OnePhase P2 { get; set; }
        public OnePhase P3 { get; set; }
        public OnePhase P4 { get; set; }

        public void GetValues(byte[] data)
        {
            /*
             * 串口读取值的解释
             * 
             * P1.V = ……
             */
        }
    }
class Test
    {
        public enum Powermeters { 远方, 横河 };

        public Test()
        {
            PowerMeter1 = new PF9830();
            PowerMeter2 = new WT230();
            Port = new SerialPort();
            Port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);
        }        

        public PF9830 PowerMeter1 { get; set; }

        public WT230 PowerMeter2 { get; set; }

        public SerialPort Port { get; set; }

        private Powermeters flag;

        void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int length = Port.BytesToRead;
            byte[] data = new byte[length];
            Port.Read(data, 0, length);
            switch (flag)
            {
                case Powermeters.横河:
                    PowerMeter2.GetValues(data);
                    break;
                case Powermeters.远方:
                    PowerMeter1.GetValues(data);
                    break;
                default:
                    break;
            }         
        }
    }

这里我们会发现WT230与PF9830两个类中有很多相同的代码,只是GetValues()这个方法不现。
再的就是实现类的有两个实例PowerMeter1与PowerMeter2,这与UI交互方面会存在很大的问题。

这里我们如果运用抽象类就可以很容易的解决上面的两个问题

首先我们先抽象出一个 功率计 的类出来:

 public abstract class PowerMeterBase
    {
        public PowerMeterBase()
        {
            P1 = new OnePhase();
            P2 = new OnePhase();
            P3 = new OnePhase();
            P4 = new OnePhase();
        }

        public OnePhase P1 { get; set; }
        public OnePhase P2 { get; set; }
        public OnePhase P3 { get; set; }
        public OnePhase P4 { get; set; }

        public abstract void GetValues(byte[] data);//抽象方法
    }

然后实例远方与横河的类

 public class PF9830:PowerMeterBase
    {  
        public override void GetValues(byte[] data)
        {
            /*
             * 串口读取值的解释
             * 
             * P1.V = ……
             */
        }
    }
public class WT230:PowerMeterBase
    {  
        public override void GetValues(byte[] data)
        {
            /*
             * 串口读取值的解释
             * 
             * P1.V = ……
             */
        }
    }

现在我们实现的UI交互类就简单多了

class Test
    {
        public enum Powermeters { 远方, 横河 };

        public Test()
        {     
            Port = new SerialPort();
            Port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);
        }

        public PowerMeterBase PowerMeter { get; set; } //实现多态

        public SerialPort Port { get; set; }

        private Powermeters flag;

        void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int length = Port.BytesToRead;
            byte[] data = new byte[length];
            Port.Read(data, 0, length);
            switch (flag)
            {
                case Powermeters.横河:
                    PowerMeter = new WT230();
                    PowerMeter.GetValues(data);
                    break;
                case Powermeters.远方:
                    PowerMeter = new PF9830();
                    PowerMeter.GetValues(data);
                    break;
                default:
                    break;
            }         
        }
    }

 

总结:

  功率计(抽象类)WT230(实类)PF9830(实类)

  对不同功率计的显示(多态)

 

posted @ 2014-09-06 00:09  枯无穷肉  阅读(273)  评论(0编辑  收藏  举报