2.對象是一個地地道道的指針
從物理角度來看,對象就是一段地址空間,這段地址空間的標(biāo)志就是我們定義的
類“變量”。所以我們可以把對象看成一個類的指針。大家知道,要訪問一個指針就
必須對指針初始化。對象的既然是一個指針,也必須對它進(jìn)行初始化。如何初始化呢?
還是說指針的初始化吧。對于一個指針可以有以下兩種方法來進(jìn)行初始化:
(一)直接分配
var
Pint:^Integer;
begin
new(Pint);
Pint^:=12;
Dispose(Pint);
end;
(二)指向別的已分配空間的變量
var
Pint:^Integer;
i:integer;
begin
i:=12;
Pint:=@i;
end;
有趣的是,對象這種“指針”也有兩種方法初始化
(一)直接分配
var
AForm:TForm;
begin
AForm:=TForm.Create(Self);
AForm.ShowModal;
AForm.Free;
end;
(二)指向別的已分配空間的實(shí)例
var
AForm:TForm;
begin
AForm:=Self;
AForm.Caption:='知道了嗎?為什么會這樣呢';
end;
file://這個AForm和它所指向的Form實(shí)例共用同一段地址單元,所有對AForm操作都將反應(yīng)
file://到它所對應(yīng)的Form實(shí)例之上。
說到這,我們就很好解釋為什么過程(函數(shù))的對象參數(shù)傳遞時,象這樣這的格式:
(一)PRocedure SetEdit(var Edit:TEdit);
begin
Edit.Text:='11';
end;
和
(二)procedure SetEdit(Edit:TEdit);
begin
Edit.Text:='11';
end;
效果是一樣的了。(一)是把一個TEdit實(shí)體作為參數(shù)引用的形式進(jìn)行參數(shù)傳遞,(二)是
把一個TEdit的對象“指針”作為參數(shù)傳遞。
3.類可以理解成一種特殊的數(shù)據(jù)類型
我們知道數(shù)據(jù)類型可以進(jìn)行強(qiáng)制類型轉(zhuǎn)化,類即然可以理解成一種數(shù)據(jù)類型,那
么它也應(yīng)該可以進(jìn)行類類型轉(zhuǎn)。比方如下代碼為一個按鈕(Button1)的單擊事件:
(一)
procedure TForm1.Button1Click(Sender: TObject);
var
ACaption:String;
begin
ACaption:=TButton(Sender).Caption;//Sender從TObject轉(zhuǎn)化到TButton
ShowMessage(Format('You clicked ''%s'' !',[ACaption]));
end;
在這段代碼中,Sender是一個TObject型對象,我們把它強(qiáng)制轉(zhuǎn)化為TButton類型。如你
看得不清楚,可以參照一下我們通常的數(shù)據(jù)類型的轉(zhuǎn)化:
(二)
procedure TForm1.Button1Click(Sender: TObject);
var
S_Str:String;
P_Str:PChar;
begin
S_Str:='I love China!';
P_Str:=PChar(S_Str);
S_Str:='';
S_Str:=String(P_Str);
ShowMessage(S_Str);
end;
但是在面對對象的程序設(shè)計(jì)過程中,強(qiáng)調(diào)的是安全性,如(一)的強(qiáng)制類型轉(zhuǎn)化存在著不
安全性。如下的代碼,依然是寫B(tài)utton1.OnClick事件:
(三)
procedure TForm1.Button1Click(Sender: TObject);
begin
TCanvas(Sender).Brush.Color:=clRed;
end;
執(zhí)行一下,就會出錯。這樣豈不是違背了面對對象的程序設(shè)計(jì)的宗旨了嗎?沒有,即然
是類,就應(yīng)該有類特定的類強(qiáng)制轉(zhuǎn)化方法,改(三)的方法如下:
(四)
procedure TForm1.Button1Click(Sender: TObject);
begin
(Sender as TCanvas).Brush.Color:=clRed;
end;//用as來轉(zhuǎn)化,as就可以把錯誤抓住,不會影響程序的正常運(yùn)行。
說到這我順便提一下VB吧,如果學(xué)過VB的人可能覺得其中的控件數(shù)組比較爽,尤其是在
編寫象計(jì)算器這樣的程序時。但Delphi給我們什么呢?答案是Delphi也能快速簡潔的開
發(fā)出這樣的程序。如是操作:在窗體上放一個Edit和十個Button,把Button.Caption分
別設(shè)為'0','1','2',...'9',然后寫一個按鈕的OnClick事件如下:
(五)
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+(Sender as TButton).Caption;
end;
把別的Button的OnClick事件都關(guān)聯(lián)到Button1Click上,運(yùn)行程序。拍拍手!這樣計(jì)算器
程序的雛形就具備了。我們用Delphi的類類型轉(zhuǎn)化,開發(fā)出來類似VB中的控件數(shù)組功能
的程序也是很棒的嘛!:)
4.抽象類和它的實(shí)例
Delphi中有一種類為抽象類,你不能天真的直接為它創(chuàng)建一個實(shí)例。如:TStrings
類。如下代碼:
(一)
var
StrLst:TStrings;
begin
StrLst:=TStrings.Create;
StrLst.Add('I love Japan!');
StrLst.Free;
end;
這是不對的。那如何為諸如TStrings這樣的抽象類構(gòu)造實(shí)例呢?答案是借助它的非抽
象子類。我們知道TStrings有一個TStringList非抽象子類。我們就可以這樣作:
(二)
var
StrLst:TStrings;
begin
StrLst:=TStringList.Create;//借助其子類的構(gòu)造器,對StrLst進(jìn)行子類化
StrLst.Add('I love China!');
StrLst.Free;
end;
(三)
var
StrLst:TStringList;
begin
StrLst:=TStringList.Create;
file://放棄吧,不要再用抽象類,完全用它的“兒子”來你的事吧
StrLst.Add('I love China!');
StrLst.Free;
end;
5.類是一種對數(shù)據(jù)和操作高度的封裝機(jī)制
(一)數(shù)據(jù)封裝
unit Unit2;
interface
type
TEmployee=class
private
FName:String;
public
Constructor Create;
function GetName:String;
procedure SetName(AName:String);
end;
implementation
{ TEmployee }
constructor TEmployee.Create;
begin
FName:='BlazingFire';
end;
function TEmployee.GetName: String;
begin
Result:=FName;
end;
procedure TEmployee.SetName(AName: String);
begin
FName:=AName;
end;
end.
如上代碼,我們就用了一個過程SetName和一個函數(shù)GetName對私有變量FName進(jìn)行完全的
封裝。我們要對FName操作就只有這樣:
uses
unit2;
procedure TForm1.Button1Click(Sender: TObject);
var
AEmployee:TEmployee;
begin
AEmployee:=TEmployee.Create;
AEmployee.SetName('Rose');//利用SetName來設(shè)置FName
MessageBox(Handle,PChar(AEmployee.GetName),'Empoyee',0);
file://用GetName來訪問FName
AEmployee.Free;
end;
(二)操作封裝
unit Unit2;
interface
type
TDivision=Class
public
file://多態(tài)性讓你的程序更據(jù)有“柔韌性”
function GetDiv(Num1,Num2:Double):Double;overload;
function GetDiv(Num1,Num2:integer):integer;overload;
end;
implementation
{ Division }
function TDivision.GetDiv(Num1, Num2: Double): Double;
begin
try
Result:=Num1/Num2;
except
Result:=0;//提供彈形處理機(jī)制,處理除數(shù)為0情況
end;
end;
function TDivision.GetDiv(Num1, Num2: integer): integer;
begin
try
Result:=Num1 div Num2;
except
Result:=0;//提供彈形處理機(jī)制,處理除數(shù)為0情況
end;
end;
end.
如上代碼我們通過類的多態(tài)性機(jī)制把除法分別處理成整除和非整除,又通過異常處理屏
去除數(shù)為0的情況,從而保證操作的安全性,在調(diào)用時,我們就可以這樣來:
uses
unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Division:TDivision;
IValue:integer;
FValue:Double;
begin
Division:=TDivision.Create;
IValue:=Division.GetDiv(1,2);
FValue:=Division.GetDiv(1.0,2);
IValue:=Division.GetDiv(1,0);
FValue:=Division.GetDiv(1.0,0);
Division.Free;
end;
6.類是一種代碼重用機(jī)制
比方在5中我們想對這個類加上一個GetAdd函數(shù)來作加法運(yùn)算就可以用類的繼承。如
下寫就可以了:
(一)
unit Unit2;
interface
type
TDivision=Class
public
function GetDiv(Num1,Num2:Double):Double;overload;
function GetDiv(Num1,Num2:integer):integer;overload;
end;
type
TOperation=Class(TDivision)
public
function GetAdd(Num1,Num2:Double):Double;
end;
implementation
{ Division }
function TDivision.GetDiv(Num1, Num2: Double): Double;
begin
try
Result:=Num1/Num2;
except
Result:=0;
end;
end;
function TDivision.GetDiv(Num1, Num2: integer): integer;
begin
try
Result:=Num1 div Num2;
except
Result:=0;
end;
end;
{ TOperation }
function TOperation.GetAdd(Num1, Num2: Double): Double;
begin
Result:=Num1+Num2;
end;
end.
這里我們從TDivision繼承了一個子類TOperation。TOperation就可以即有TDivsion
公有方法GetDiv,又有自己的獨(dú)特的方法GetAdd。這是類為我們提供的“魚和熊掌兼
得”之法。不錯吧。:)
新聞熱點(diǎn)
疑難解答
圖片精選