類的使用---進階編程篇(四)


  很多講解編程的書籍在介紹類的時候就直接介紹屬性,字段,方法,事件等等,然后說下多態性,繼承性,等等,所有的這些東西對於初學者來說實在是虛無縹緲,對於什么地方該用類,該怎么設計類仍然是很模糊的,需要經驗大量的編程實踐才能摸索到里面的經驗,所以本節在講解的時候,會側重於舉例子來說明,為什么需要使用類,怎么使用類,至於類的繼承也會針對特定的情況來說明,讓大家對於類有個清晰的概念。

 

為什么需要使用類

  理解這個問題對於學習編程的人非常的關鍵,對於有經驗的人來說,可能會回答,類可以分離功能,形成功能模塊,進而實現模塊開發,易於調試和代碼維護。對於初學者來說,鬼知道你在說什么啊!根本理解不了,需要多寫幾次類以后才能深刻的理解這些思想,所以此處會從更基礎的情況進行說明,假設我們有一台設備,上面有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     }

  至此,已經將軟件開發思路大致講完,后面的類的多態性需要另開一片文章講解,一個好的軟件系統需要花大量的時間不停的去優化,調整,路漫漫其修遠兮。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM