zoukankan      html  css  js  c++  java
  • 类的使用---进阶编程篇(四)

      很多讲解编程的书籍在介绍类的时候就直接介绍属性,字段,方法,事件等等,然后说下多态性,继承性,等等,所有的这些东西对于初学者来说实在是虚无缥缈,对于什么地方该用类,该怎么设计类仍然是很模糊的,需要经验大量的编程实践才能摸索到里面的经验,所以本节在讲解的时候,会侧重于举例子来说明,为什么需要使用类,怎么使用类,至于类的继承也会针对特定的情况来说明,让大家对于类有个清晰的概念。

    为什么需要使用类

      理解这个问题对于学习编程的人非常的关键,对于有经验的人来说,可能会回答,类可以分离功能,形成功能模块,进而实现模块开发,易于调试和代码维护。对于初学者来说,鬼知道你在说什么啊!根本理解不了,需要多写几次类以后才能深刻的理解这些思想,所以此处会从更基础的情况进行说明,假设我们有一台设备,上面有5个参数需要实时在软件上显示,作为初学者,我们会这么写:(1s定时器模拟了读取设备的场景)

    代码如下所示:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Data;
     5 using System.Drawing;
     6 using System.Linq;
     7 using System.Text;
     8 using System.Threading.Tasks;
     9 using System.Windows.Forms;
    10 
    11 namespace WindowsFormsApp1
    12 {
    13     public partial class Form1 : Form
    14     {
    15         public Form1()
    16         {
    17             InitializeComponent();
    18         }
    19 
    20         private Timer TimerReadMachine = null;
    21 
    22         private void Form1_Load(object sender, EventArgs e)
    23         {
    24             //初始化时钟
    25             TimerReadMachine = new Timer();
    26             TimerReadMachine.Interval = 1000;
    27             TimerReadMachine.Tick += TimerReadMachine_Tick;
    28         }
    29 
    30         private void TimerReadMachine_Tick(object sender, EventArgs e)
    31         {
    32             Random r = new Random();
    33             label1.Text = "温度1:" + r.Next(100, 300) + "";
    34             label2.Text = "温度2:" + r.Next(100, 300) + "";
    35             label3.Text = "温度3:" + r.Next(100, 300) + "";
    36             label4.Text = "温度4:" + r.Next(100, 300) + "";
    37             label5.Text = "温度5:" + r.Next(100, 300) + "";
    38         }
    39 
    40         private void Form1_Shown(object sender, EventArgs e)
    41         {
    42             //启动定时器
    43             TimerReadMachine.Start();
    44         }
    45 
    46         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    47         {
    48             if (MessageBox.Show("是否真的退出窗口?", "退出确认", MessageBoxButtons.YesNo) == DialogResult.No)
    49             {
    50                 e.Cancel = true;
    51             }
    52         }
    53 
    54         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    55         {
    56         }
    57 
    58 
    59         private void button1_Click(object sender, EventArgs e)
    60         {
    61             Button button = new Button();
    62             button.Location = new System.Drawing.Point(328, 42);
    63             button.Name = "button2";
    64             button.Size = new System.Drawing.Size(75, 23);
    65             button.TabIndex = 0;
    66             button.Text = "button2";
    67             button.UseVisualStyleBackColor = true;
    68             button.Click += Button_Click;
    69 
    70             this.Controls.Add(button);
    71         }
    72 
    73         private void Button_Click(object sender, EventArgs e)
    74         {
    75             MessageBox.Show("你点击了button2");
    76         }
    77 
    78 
    79 
    80     }
    81 }

      上述的代码有部分是上一章节的代码,所以自行忽略,如果碰到上述的情况,只是将数据显示一下就完事了还算简单了,但实际情况更加复杂,通常需要缓存这五个温度的数据,一遍根据需要进行获取计算其他的需求,比如说,温度的幅度区间,最大值最小值,温度的平均值,温度变大了还是变小了判定,等等情况,所以我们会将代码改成下面这样的:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Data;
     5 using System.Drawing;
     6 using System.Linq;
     7 using System.Text;
     8 using System.Threading.Tasks;
     9 using System.Windows.Forms;
    10 
    11 namespace WindowsFormsApp1
    12 {
    13     public partial class Form1 : Form
    14     {
    15         public Form1()
    16         {
    17             InitializeComponent();
    18         }
    19 
    20         private Timer TimerReadMachine = null;
    21 
    22         private void Form1_Load(object sender, EventArgs e)
    23         {
    24             //初始化时钟
    25             TimerReadMachine = new Timer();
    26             TimerReadMachine.Interval = 1000;
    27             TimerReadMachine.Tick += TimerReadMachine_Tick;
    28         }
    29 
    30         int Temperature1 = 0;
    31         int Temperature2 = 0;
    32         int Temperature3 = 0;
    33         int Temperature4 = 0;
    34         int Temperature5 = 0;
    35 
    36         private void TimerReadMachine_Tick(object sender, EventArgs e)
    37         {
    38             Random r = new Random();
    39             int temp1 = r.Next(100, 300);
    40             int temp2 = r.Next(100, 300);
    41             int temp3 = r.Next(100, 300);
    42             int temp4 = r.Next(100, 300);
    43             int temp5 = r.Next(100, 300);
    44             label1.Text = "温度1:" + temp1 + "" + (temp1 > Temperature1 ? "变大了" : "变小了");
    45             label2.Text = "温度2:" + temp2 + "" + (temp2 > Temperature2 ? "变大了" : "变小了");
    46             label3.Text = "温度3:" + temp3 + "" + (temp3 > Temperature3 ? "变大了" : "变小了");
    47             label4.Text = "温度4:" + temp4 + "" + (temp4 > Temperature4 ? "变大了" : "变小了");
    48             label5.Text = "温度5:" + temp5 + "" + (temp5 > Temperature5 ? "变大了" : "变小了");
    49 
    50             Temperature1 = temp1;
    51             Temperature2 = temp2;
    52             Temperature3 = temp3;
    53             Temperature4 = temp4;
    54             Temperature5 = temp5;
    55         }
    56 
    57         private void Form1_Shown(object sender, EventArgs e)
    58         {
    59             //启动定时器
    60             TimerReadMachine.Start();
    61         }
    62 
    63         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    64         {
    65             if (MessageBox.Show("是否真的退出窗口?", "退出确认", MessageBoxButtons.YesNo) == DialogResult.No)
    66             {
    67                 e.Cancel = true;
    68             }
    69         }
    70 
    71         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    72         {
    73         }
    74 
    75 
    76         private void button1_Click(object sender, EventArgs e)
    77         {
    78             Button button = new Button();
    79             button.Location = new System.Drawing.Point(328, 42);
    80             button.Name = "button2";
    81             button.Size = new System.Drawing.Size(75, 23);
    82             button.TabIndex = 0;
    83             button.Text = "button2";
    84             button.UseVisualStyleBackColor = true;
    85             button.Click += Button_Click;
    86 
    87             this.Controls.Add(button);
    88         }
    89 
    90         private void Button_Click(object sender, EventArgs e)
    91         {
    92             MessageBox.Show("你点击了button2");
    93         }
    94 
    95 
    96 
    97     }
    98 }

      效果如下:

      在实际的开发中,一台设备的参数通常是几十个或是上百个的数量级,或许你会说,我可以定义100个label啊,假设要监视100台设备呢,还要定义10000个label吗,显示是不可能的,再想想如果以后碰到需要追加一个参数的时候怎么办(或许你会说,我会和工艺部门再三确认这些参数是不是足够了,别人也保证了以后不再添加参数,事实上这根本没什么卵用),再添加一台设备呢,你还要再定义那么多数据吗?

      为了解决上述留下来的编程困难,我们需要用到类的知识来解决,我们想要一种什么样子的解决方案呢,首先肯定不希望重复定义那么多的参数吧,定义一台设备也就算了,2台的话,勉强复制下算了,超过10台,即时是复制粘贴也会受不了,其次希望多一台设备的情况下,稍微修改下代码就可以实现。

      我们把一台设备定义一个类,那么属性就很多解决了,无非就是5个参数点,那么这个类就设计完成了:

    1     public class HslMachine
    2     {
    3         public int Temperature1 { get; set; }
    4         public int Temperature2 { get; set; }
    5         public int Temperature3 { get; set; }
    6         public int Temperature4 { get; set; }
    7         public int Temperature5 { get; set; }
    8     }

      设计好类后,接着开始改造代码,把原先的代码改造成使用类完成的:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Drawing;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Threading.Tasks;
      9 using System.Windows.Forms;
     10 
     11 namespace WindowsFormsApp1
     12 {
     13     public partial class Form1 : Form
     14     {
     15         public Form1()
     16         {
     17             InitializeComponent();
     18         }
     19 
     20         private Timer TimerReadMachine = null;
     21 
     22         private void Form1_Load(object sender, EventArgs e)
     23         {
     24             //初始化时钟
     25             TimerReadMachine = new Timer();
     26             TimerReadMachine.Interval = 1000;
     27             TimerReadMachine.Tick += TimerReadMachine_Tick;
     28         }
     29 
     30         HslMachine machine1 = new HslMachine();
     31 
     32         private void TimerReadMachine_Tick(object sender, EventArgs e)
     33         {
     34             Random r = new Random();
     35             int temp1 = r.Next(100, 300);
     36             int temp2 = r.Next(100, 300);
     37             int temp3 = r.Next(100, 300);
     38             int temp4 = r.Next(100, 300);
     39             int temp5 = r.Next(100, 300);
     40             label1.Text = "温度1:" + temp1 + "" + (temp1 > machine1.Temperature1 ? "变大了" : "变小了");
     41             label2.Text = "温度2:" + temp2 + "" + (temp2 > machine1.Temperature2 ? "变大了" : "变小了");
     42             label3.Text = "温度3:" + temp3 + "" + (temp3 > machine1.Temperature3 ? "变大了" : "变小了");
     43             label4.Text = "温度4:" + temp4 + "" + (temp4 > machine1.Temperature4 ? "变大了" : "变小了");
     44             label5.Text = "温度5:" + temp5 + "" + (temp5 > machine1.Temperature5 ? "变大了" : "变小了");
     45 
     46             machine1.Temperature1 = temp1;
     47             machine1.Temperature2 = temp2;
     48             machine1.Temperature3 = temp3;
     49             machine1.Temperature4 = temp4;
     50             machine1.Temperature5 = temp5;
     51         }
     52 
     53         private void Form1_Shown(object sender, EventArgs e)
     54         {
     55             //启动定时器
     56             TimerReadMachine.Start();
     57         }
     58 
     59         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
     60         {
     61             if (MessageBox.Show("是否真的退出窗口?", "退出确认", MessageBoxButtons.YesNo) == DialogResult.No)
     62             {
     63                 e.Cancel = true;
     64             }
     65         }
     66 
     67         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
     68         {
     69         }
     70 
     71 
     72         private void button1_Click(object sender, EventArgs e)
     73         {
     74             Button button = new Button();
     75             button.Location = new System.Drawing.Point(328, 42);
     76             button.Name = "button2";
     77             button.Size = new System.Drawing.Size(75, 23);
     78             button.TabIndex = 0;
     79             button.Text = "button2";
     80             button.UseVisualStyleBackColor = true;
     81             button.Click += Button_Click;
     82 
     83             this.Controls.Add(button);
     84         }
     85 
     86         private void Button_Click(object sender, EventArgs e)
     87         {
     88             MessageBox.Show("你点击了button2");
     89         }
     90 
     91 
     92 
     93     }
     94 
     95 
     96     public class HslMachine
     97     {
     98         public int Temperature1 { get; set; }
     99         public int Temperature2 { get; set; }
    100         public int Temperature3 { get; set; }
    101         public int Temperature4 { get; set; }
    102         public int Temperature5 { get; set; }
    103     }
    104 }

      或许你会说,你看嘛,根本没有方便多少,而且写的代码还更多了,在只有一台设备的情况下,确实如你所说,代码更难了,却没有实现更多的功能。但是,,,,,但是,,,,,你想想,如果你再增加一台设备呢???

    1         HslMachine machine1 = new HslMachine();
    2         HslMachine machine2 = new HslMachine();

      这样就解决拉!!!!!再增加一台的话,那就再实例化一个对象,可能你又会说,我要是有100台设备,还要实例化100个对象吗,要是如果10000台设备呢?接下来激动人心的时刻到了,假设我们有10000台设备,应该怎么做呢?

    1         private HslMachine[] hslMachines = new HslMachine[10000];//声明10000台设备的对象

      这样一来,就算你有1亿台设备我也能实例化完成(假设一台设备1万元,总值1万亿,所以几乎不可能),需要注意的是,这个数组对象虽然实例化完成了,1万台设备还需要自己实例化,不然就是空引用。当设备比较多的时候,再初始化数据的地方我们也要修改,不然每台设备都这么写就要复制很多次了,这里精简的过程就是方法的提炼,我们让设备类支持自我初始化,所以新增一个方法:

     1     public class HslMachine
     2     {
     3         public int Temperature1 { get; set; }
     4         public int Temperature2 { get; set; }
     5         public int Temperature3 { get; set; }
     6         public int Temperature4 { get; set; }
     7         public int Temperature5 { get; set; }
     8 
     9         /// <summary>
    10         /// 初始化数据
    11         /// </summary>
    12         /// <param name="r">假想r是传进来的设备底层数据</param>
    13         public void Initialization(Random r)
    14         {
    15             int temp1 = r.Next(100, 300);
    16             int temp2 = r.Next(100, 300);
    17             int temp3 = r.Next(100, 300);
    18             int temp4 = r.Next(100, 300);
    19             int temp5 = r.Next(100, 300);
    20 
    21             Temperature1 = temp1;
    22             Temperature2 = temp2;
    23             Temperature3 = temp3;
    24             Temperature4 = temp4;
    25             Temperature5 = temp5;
    26         }
    27     }

      但是这样做了又发生一个问题,我们在窗体程序中就不知道一个数据的状态是变大变小还是不变了,所以我们需要改造温度的数据。使得温度的数据也是一个类,这样可以使得温度数据包含更多的特性,甚至是最大值,最小值,参数名称

     1  public class MachineParameter
     2     {
     3         public string ParameterName { get; set; }
     4         public int Temperature { get; set; }
     5         public int Status { get; set; }
     6 
     7         public int TemperatureMax { get; set; } = int.MinValue;
     8 
     9         public int TemperatureMin { get; set; } = int.MaxValue;
    10     }
    11 
    12     public class HslMachine
    13     {
    14         public MachineParameter Temperature1 = new MachineParameter()
    15         {
    16             ParameterName = "温度1"
    17         };
    18         public MachineParameter Temperature2 = new MachineParameter()
    19         {
    20             ParameterName = "温度2"
    21         };
    22         public MachineParameter Temperature3 = new MachineParameter()
    23         {
    24             ParameterName = "温度3"
    25         };
    26         public MachineParameter Temperature4 = new MachineParameter()
    27         {
    28             ParameterName = "温度4"
    29         };
    30         public MachineParameter Temperature5 = new MachineParameter()
    31         {
    32             ParameterName = "温度5"
    33         };
    34 
    35         /// <summary>
    36         /// 初始化数据
    37         /// </summary>
    38         /// <param name="r">假想r是传进来的设备底层数据</param>
    39         public void Initialization(Random r)
    40         {
    41             int temp1 = r.Next(100, 300);
    42             int temp2 = r.Next(100, 300);
    43             int temp3 = r.Next(100, 300);
    44             int temp4 = r.Next(100, 300);
    45             int temp5 = r.Next(100, 300);
    46 
    47             SetValue(Temperature1, temp1);
    48             SetValue(Temperature2, temp2);
    49             SetValue(Temperature3, temp3);
    50             SetValue(Temperature4, temp4);
    51             SetValue(Temperature5, temp5);
    52         }
    53 
    54         private void SetValue(MachineParameter para,int value)
    55         {
    56             if(para.Temperature>value)
    57             {
    58                 para.Status = 1;
    59             }
    60             else if(para.Temperature == value)
    61             {
    62                 para.Status = 0;
    63             }
    64             else
    65             {
    66                 para.Status = -1;
    67             }
    68 
    69 
    70             if (para.TemperatureMax < value) para.TemperatureMax = value;
    71             if (para.TemperatureMin > value) para.TemperatureMin = value;
    72 
    73             para.Temperature = value;
    74         }
    75     }

      到此为止,设备的类已经初具成形了,如果参数想要支持更多的特性,也方便进行扩充,如果再添加一些其他的参数信息,这个类编写的就相当棒了。接下来就是显示了,这次假设有50台设备,只显示一台设备,不同的设备进行手动切换显示,并显示参数变大变小区别。界面重新调整:

      然后界面的代码重新设计:

      1 namespace WindowsFormsApp1
      2 {
      3     public partial class Form1 : Form
      4     {
      5         public Form1()
      6         {
      7             InitializeComponent();
      8         }
      9 
     10         private Timer TimerReadMachine = null;
     11 
     12         private void Form1_Load(object sender, EventArgs e)
     13         {
     14             //初始化时钟
     15             TimerReadMachine = new Timer();
     16             TimerReadMachine.Interval = 1000;
     17             TimerReadMachine.Tick += TimerReadMachine_Tick;
     18 
     19             int[] datas = new int[hslMachines.Length];
     20             //设备实例化
     21             for (int i = 0; i < hslMachines.Length; i++)
     22             {
     23                 hslMachines[i] = new HslMachine();
     24                 datas[i] = i + 1;
     25             }
     26             //初始化组合框
     27             comboBox1.SelectedIndexChanged += ComboBox1_SelectedIndexChanged;
     28             comboBox1.DataSource = datas;
     29         }
     30 
     31         private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
     32         {
     33             //选择发生了变化
     34             ShowSpecifiedMachine();
     35         }
     36 
     37         private HslMachine[] hslMachines = new HslMachine[50];//声明10000台设备的对象
     38 
     39         private void TimerReadMachine_Tick(object sender, EventArgs e)
     40         {
     41             Random r = new Random();
     42 
     43             for (int i = 0; i < hslMachines.Length; i++)
     44             {
     45                 hslMachines[i].Initialization(r);
     46             }
     47 
     48             ShowSpecifiedMachine();
     49         }
     50 
     51         private void ShowSpecifiedMachine()
     52         {
     53             int i = comboBox1.SelectedIndex;
     54             HslMachine machine = hslMachines[i];
     55             ShowTemperatureChange(label1, label10, machine.Temperature1);
     56             ShowTemperatureChange(label2, label9, machine.Temperature2);
     57             ShowTemperatureChange(label3, label8, machine.Temperature3);
     58             ShowTemperatureChange(label4, label7, machine.Temperature4);
     59             ShowTemperatureChange(label5, label6, machine.Temperature5);
     60         }
     61 
     62         private void ShowTemperatureChange(Label label_1, Label label_2,MachineParameter para)
     63         {
     64             label_1.Text = para.ParameterName + "" + para.Temperature + "";
     65             switch (para.Status)
     66             {
     67                 case -1: label_2.BackColor = Color.LimeGreen; break;
     68                 case 1: label_2.BackColor = Color.Tomato; break;
     69                 default: label_2.BackColor = SystemColors.Control; break;
     70             }
     71         }
     72 
     73         private void Form1_Shown(object sender, EventArgs e)
     74         {
     75             //启动定时器
     76             TimerReadMachine.Start();
     77         }
     78 
     79         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
     80         {
     81             if (MessageBox.Show("是否真的退出窗口?", "退出确认", MessageBoxButtons.YesNo) == DialogResult.No)
     82             {
     83                 e.Cancel = true;
     84             }
     85         }
     86 
     87         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
     88         {
     89         }
     90 
     91 
     92         private void button1_Click(object sender, EventArgs e)
     93         {
     94             Button button = new Button();
     95             button.Location = new System.Drawing.Point(328, 42);
     96             button.Name = "button2";
     97             button.Size = new System.Drawing.Size(75, 23);
     98             button.TabIndex = 0;
     99             button.Text = "button2";
    100             button.UseVisualStyleBackColor = true;
    101             button.Click += Button_Click;
    102 
    103             this.Controls.Add(button);
    104         }
    105 
    106         private void Button_Click(object sender, EventArgs e)
    107         {
    108             MessageBox.Show("你点击了button2");
    109         }
    110 
    111 
    112 
    113     }

      至此,已经将软件开发思路大致讲完,后面的类的多态性需要另开一片文章讲解,一个好的软件系统需要花大量的时间不停的去优化,调整,路漫漫其修远兮。

  • 相关阅读:
    三层框架(原始版)
    Java虚拟机之内存区域
    JDK和JRE的区别
    cookie和session区别与联系
    DAO、Service、Controller及View层级结构梳理
    JavaWeb-四大域对象复习
    Mybatis-实现逆向代理
    Springboot-实现热部署
    排序算法-冒泡排序
    【ERROR 1064 (42000)】MySQL中使用mysqladmin或set修改root密码时提示语法错误
  • 原文地址:https://www.cnblogs.com/dathlin/p/7245602.html
Copyright © 2011-2022 走看看