國內有許多人將Delphi作為首選的開發工具。原因當然是因為Delphi提供了許多特性給開發者:物件導向的開發,視覺化介面設計,元件豐富,多平台的可移植性(Delphi6的新特性)。
可是對於初學者來說,物件導向的想法可能並不是Delphi帶給其的最大的感受。而視覺化的介面設計,豐富多樣的可用組件反而給其留下最深刻難忘的印象。由此帶來的嚴重的後果是,初學者往往在很長一段時間裡,只將注意力集中在Delphi提供的現有的VCL組件的使用上,而忽略去思考面向對象的思想對於Delphi的整個組件構架體系所蘊含的意義。
下面的一段程式碼,包含了一個最常見的,也是初學者最易犯的一個錯誤,這個錯誤雖然不是語法錯誤,但是卻顯露出使用者的面向對象的思想還有待加強:
var
Form1: TForm1;
implementation
{$R *.dfm}
PRocedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Form1.Caption); // <-- 這裡的Form1的使用就有些問題。
end;
這樣的程式碼,粗看看好像沒有什麼錯。但是,這裡Form1的出現就有些說不過去了。明明這裡的程式碼,寫的是TForm1的ButtonClick方法的實現,而Form1作為TForm1類的一個實例,居然被寫死到類的實現中,難道不是有些概念混亂嗎?要改成符合面向對象思想的,也很簡單,可以有兩種寫法:
1. ShowMessage(Self.Caption); // <-- 這種寫法非常明確,即將要Show的資訊是類別的目前實例的Caption
2. ShowMessage(Caption); // <-- 這裡的寫法和上述的雷同,省略了關鍵字Self;
物件導向思想的三大核心內容是封裝,繼承,多型。而上述例子暴露的問題就是封裝的問題。類似的例子還有:
var
Form1: TForm1;
.....
var
Form2: TForm2;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show; // <-- 作為一個全域的變量,Form2在這裡的使用同樣讓人覺得混亂。
end;
上述的例子,可能更有普遍性吧,對於大多數情況,在一個工程中,TForm1,和TForm2只可能各只有一個實例,所以這樣的代碼也算馬馬虎虎通過。但是從嚴格意義上來說,也是不符合封裝性的要求。參考如下代碼:
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FNext: TForm;
public
{ Public declarations }
property NextForm: TForm read FNext write FNext;
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(FNext) then
TForm2(FNext).Show;
end;
end.
// 以下是工程文件中的內容:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Form1.NextForm := Form2; // <-- 增加這麼一句,勉強讓程式碼符合封裝的要求了
Application.Run;
end.
將Form2指針,作為Form1的一個屬性,傳遞給Form1,這樣,Form1在呼叫的時候,才遵守了封裝性的原則!當然,這些程式碼只是為了體現封裝的思想,而實際中,可以依個人的習慣來決定是否真的要實現的這麼徹底。但是這種思想,應在腦子裡紮根......(未完,待續)。
更多文章