這篇文章幫我理解了面向對象和麪向過程的卻別,以及面向對象的好處!
首先得說明,“一切皆爲對象”是至理名言,至少在C#中,你應該時刻以這個理念來設計你的程序,理解這個理念對你的學習大有裨益。C#作爲一種面對對象的語言,而不是面向過程,體現在它的各個語言元素和語法結構都在爲構造對象而服務。繼承、封裝、多態等等,都是打造對象的工具利器,這在面向過程的語言中,是不能獲得充分支持的。然而認爲只要程序中出現了繼承、封裝、多態等等手段就認爲所打造的程序是面對對象的,這無疑是片面和不正確的。繼承、封裝、多態僅僅是對象的一種表面特徵,正如車輪是汽車的一種表面特徵一樣,然而有車輪的不一定就是汽車,也許是飛機。對象必定具有繼承、封裝、多態其中至少一個特徵,我認爲封裝是最基本的一個,至少應當具備封裝的特性。而如果你以面向過程來理解、構造你的程式,即使你使用了所有的手段,也許打造出來的仍然是個面向過程的程序。
理解“對象”的確是個比較難的事情,當然這是在你還未理解“對象”的前提下。
我們來實際寫個程序,看看面向對象和麪向過程究竟是如何處理的。這也許有助於你跨過這個難關。
這是一個類似於表格的程序。在窗體上放置9個Label,其中Label1,Label2,Label3排成第1行,Label4,Label5,Label6排成第2行,Label7,Label8,Label9排成第3行,形成3*3的表格樣式。再放置一個TextBox,一個Button。客戶要求:在TextBox中填寫一個數字,代表行數,然後點擊Button,對應行的Label的背景色變爲紅色。
面向過程的寫法:
private void button1_Click(object sender, EventArgs e)
{
int row = Convert.ToInt32(textBox1.Text); //行數
switch (row)
{
case 1: //第一行
label1.BackColor = Color.Red;
label2.BackColor = Color.Red;
label3.BackColor = Color.Red;
break;
case 2: //第二行
label4.BackColor = Color.Red;
label5.BackColor = Color.Red;
label6.BackColor = Color.Red;
break;
case 3: //第三行
label7.BackColor = Color.Red;
label8.BackColor = Color.Red;
label9.BackColor = Color.Red;
break;
default :
break;
}
}
執行它,代碼很出色的完成了任務。至少在現在,它讓我們非常的滿意,而且代碼也不多,還算簡潔。
好了,來看面向對象的方法。在寫程序前,先想下,客戶是怎麼要求的,嗯,窗體中雖然有9個各不相干的Label,然而客戶是要我們以“行”的概念來操作的,你在窗體中找了一遍又一遍,沒有找到“行”。那麼“行”是什麼,對了,“行”就是個對象,你想出來的一個對象。來,我們一起構造個“行”的對象,這個對象的關鍵特徵是:它是多個Label的集合,它有個背景色的屬性。
class ColorRow
{
Label[] lblRow; //用於保存Label個體,這裏我們把它封裝起來了
public ColorRow(Label[] lblRow) //構造函數,傳入一個Label控件數組
{
this.lblRow = lblRow;
}
public Color BackColor //只寫的背景色屬性
{
set
{
foreach (Label lbl in lblRow)
lbl.BackColor = value;
}
}
}
好了,可以使用這個對象了。在窗體類中添加個類級ColorRow數組。
Private ColorRow[] clrRow;
在Form_Load中初始化這個數組。
private void Form1_Load(object sender, EventArgs e)
{
clrRow = new ColorRow[3];
clrRow[0] =new ColorRow(new Label[] { label1, label2, label3 });
clrRow[1] =new ColorRow(new Label[] { label4, label5, label6 });
clrRow[2] =new ColorRow(new Label[] { label7, label8, label9 });
}
在Button_Click中
private void button1_Click(object sender, EventArgs e)
{
int row = Convert.ToInt32(textBox1.Text) - 1;
clrRow[row].BackColor = Color.Red; //對象在工作
}
代碼也很好的工作了,效果和麪向過程完全一樣。那麼爲什麼要說面向對象更爲科學呢,要知道,在我所寫的這段代碼中,面向對象的寫法比面向過程的寫法所用的代碼似乎更長,而且面向過程在一個代碼塊中就可完成的工作,用面向對象的寫法竟然分佈到了幾個代碼塊才完成。仔細分析,不難感覺到,採用面向對象的方法更接近於真實世界中的認知概念,對象封裝了它內部的細節,我們在過程中(在上列代碼中,Form_Load和Button1_Click都是過程,別試圖攻擊我,Form和Button都是對象,一切皆爲對象啊)只是在操作我們自己構造的ColorRow對象,而不是直接操作那9個Label,Label已經被封裝到了ColorRow對象中了。
仍然無法理解面向對象的好處?沒關係,你的客戶會讓你理解的,而且理解深刻。客戶突然有了個新主意,能改變行的字體顏色嗎?
面向過程中,我們必須增加如下代碼:
private void button1_Click(object sender, EventArgs e)
{
…
switch (row)
{
case 1: //第一行
…
label1. ForeColor = Color.Blue;
label2. ForeColor = Color.Blue;
label3. ForeColor = Color.Blue;
break;
case … //增加類似代碼
}
}
執行它,又出色的完成了任務,不過代碼的長度幾乎長了一倍了。
面向對象,我們在對象中添加一個屬性:
class ColorRow
{
…
public Color ForeColor //只寫的前景色屬性
{
set
{
foreach (Label lbl in lblRow)
lbl.ForeColor = value;
}
}
}
在Button_Click中添加對這個屬性的修改
private void button1_Click(object sender, EventArgs e)
{
…
clrRow[row].ForeColor = Color.Blue; //對象在工作
}
改動並不大,而且思路很清晰。看出面向對象的好處了嗎?還沒有,怎麼?兩種方式的代碼量差不多,用過程也能解決採用對象來解決的所有問題。恩,對對對,可是……
你滿臉自信,不容我再囉嗦,懷抱着用過程解決一切問題的新思想,向客戶走去。客戶很靦腆,紅着臉,非常不好意思的對你說:我想,能不能讓某行可以隱藏、失效、改變字體、清除文本…..,要是能把表擴成10*10,那就太感謝您了……