首先得说明,“一切皆为对象”是至理名言,至少在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,那就太感谢您了……