日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Delphi中静态方法重载还是覆盖的讨论

發布時間:2025/4/9 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Delphi中静态方法重载还是覆盖的讨论 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Delphi中靜態方法重載還是覆蓋的討論

新人學習Delphi的時候,容易搞不懂的一個問題,當子類方法和基類方法同名,并且參數也一樣的時候,叫做什么呢?是覆蓋,還是重載呢?

?

答案是隱藏父類方法。

?

一般我們的理解重載是同名,不同參數的同一個類里面實現,

或者父類和子類方法同名,參數不同,子類必須有overide關鍵字,表示重載方法。

?

也就是說重載必須有overload修飾;

?

覆蓋呢?覆蓋必須有override修改;

?

否則同名,同參數就是隱藏方法。

=================================================================

下面是筆者自己的程序,您可以嘗試一下。

?

program?Project2;

?

{$APPTYPE?CONSOLE}

?

uses

??SysUtils;

?

??type?tclassa=class

?????private

???????age?:Integer;

?????public

???????function?getage:integer;???//靜態方法

???????function?getDat:integer;??//靜態方法

???????end;

?

???????tclassb=class(tclassa)

???????private

?

?????????public

???????????function?getdat:integer;??//隱藏靜態方法

???????????function?getage:Integer;?//隱藏靜態方法

???????????end;

?

{?tclassa?}

?

function?tclassa.getage:?integer;

begin

??age?:=?1;

??result?:=?age;

end;

?

function?tclassa.getDat:?integer;

begin

??result?:=?3;

end;

?

{?tclassb?}

?

function?tclassb.getage:?Integer;

begin

??Result?:=?1+?inherited?getage();

end;

?

var?a:tclassa;

???b:tclassb;

function?tclassb.getdat:?integer;

begin

??result?:=?1?+?inherited?getdat();

end;

?

begin

??a?:=?tclassa.Create;

??b?:=?tclassb.Create;

?

??Writeln(a.getage());

??Writeln(b.getage());

??Writeln(a.getdat());

??Writeln(b.getdat());?//?調用的是子類的隱藏后的靜態方法?

?

??readln;

?

??readln;

??a.free;

??b.free;

?

??{?TODO?-oUser?-cConsole?Main?:?Insert?code?here?}

end.

?

我們可以看到隱藏了父類方法之后,還是可以調用父類同名方法的。這就和覆蓋是相似的。

?

?

參考資料

=================================

?

Delphi面向對象方法的分類以及覆蓋隱藏和重載

<6>?方法的分類
??按用途分?普通方法,構造方法,析構方法,?類方法,消息處理方法
??按運行綁定機制分:靜態方法,虛方法,動態方法,[注意此處的靜態方法不是所謂的class?method?而是普通的方法?,靜態是指靜態編譯]
??關于析構方法,最好是用名字destroy?,這樣可以使用Free方法,而不要直接調用destroy方法.
??Free方法會先判斷對象變量是否為nil.
??procedure?TObject.Free;
??begin
????if?Self?<>?nil?then
??????Destroy;
??end;
??
??消息處理方法的例子:
??procedure?WMChar(var?message:TWMChar);message?WM_CHAR;
??問題來了.為什么在一個Control中聲明了消息處理方法,就能調用此消息處理方法呢,這里涉及到
??TObject?中Dispatch方法的秘密,我暫時沒有看懂.留作以后繼續學習
??先給出Dispatch的源碼.
??procedure?TObject.Dispatch(var?Message);
??asm
??????PUSH????ESI
??????MOV?????SI,[EDX]
??????OR??????SI,SI
??????JE??????@@default
??????CMP?????SI,0C000H
??????JAE?????@@default
??????PUSH????EAX
??????MOV?????EAX,[EAX]
??????CALL????GetDynaMethod
??????POP?????EAX
??????JE??????@@default
??????MOV?????ECX,ESI
??????POP?????ESI
??????JMP?????ECX
??
??@@default:
??????POP?????ESI
??????MOV?????ECX,[EAX]
??????JMP?????DWORD?PTR?[ECX]?+?VMTOFFSET?TObject.DefaultHandler
??end;
??
??GetDynaMethod的方法源碼如下
??procedure???????GetDynaMethod;
??asm
??????????{?->????EAX?????vmt?of?class????????????}
??????????{???????SI??????dynamic?method?index????}
??????????{?<-????ESI?pointer?to?routine??}
??????????{???????ZF?=?0?if?found?????????}
??????????{???????trashes:?EAX,?ECX???????????????}
??
??????????PUSH????EDI
??????????XCHG????EAX,ESI
??????????JMP?????@@haveVMT
??@@outerLoop:
??????????MOV?????ESI,[ESI]
??@@haveVMT:
??????????MOV?????EDI,[ESI].vmtDynamicTable
??????????TEST????EDI,EDI
??????????JE??????@@parent
??????????MOVZX???ECX,word?ptr?[EDI]
??????????PUSH????ECX
??????????ADD?????EDI,2
??????????REPNE???SCASW
??????????JE??????@@found
??????????POP?????ECX
??@@parent:
??????????MOV?????ESI,[ESI].vmtParent
??????????TEST????ESI,ESI
??????????JNE?????@@outerLoop
??????????JMP?????@@exit
??
??@@found:
??????????POP?????EAX
??????????ADD?????EAX,EAX
??????????SUB?????EAX,ECX?????????{?this?will?always?clear?the?Z-flag?!?}
??????????MOV?????ESI,[EDI+EAX*2-4]
??
??@@exit:
??????????POP?????EDI
??end;
??
<7>?方法的覆蓋,隱藏和重載??
??覆蓋是override?,重載是overload;
??隱藏是子類中的方法和父類的方法同名,而且參數相同,沒有override修飾符,則子類的方法就隱藏父類的方法.
??Example:
???...
????TChineseMan?=?class(TMan)
??????procedure?SayHello(words:string);?//打招呼
????end;?
????....
???procedure?TChineseMan.SayHello(words:?string);
???begin
?????ShowMessage('TChinese?Man?SayHello?'+words);
???end;
???...
????procedure?TForm1.Button1Click(Sender:?TObject);
????var
?????APerson:TMan;
?????AChinesePerson:TChinesePerson;
????begin
?????APerson:=TChineseMan.Create;
?????APerson.SayHello('是一名中國人');?
?????//注意了此處調用的是父類的TMan.Sayhello方法
?????//
?????ChinesePerson:=TChinesePerson.Create;
?????ChinesePerson.SayHello('是一名中國人');?//此時調用的是TChineseMan.sayHello
?????
?????//如果想要APerson調用TChineseMan.sayHello方法?應該采取強制類型轉換,強制類型轉換其實就是對象框架的范圍調整
?????TChinesePerson(APerson).SayHello('是一名中國人');?//此時調用的是TChineseMan.sayHello?????
????end;
????
<8>??可見性
??Delphi中四種類成員的保護方式:published,public,protected,private;???
??published,public?是可以最大訪問,protected是對之類是可見的,private是對子類不可見
??另外對象變量如果與其類的聲明在同一個單元中,則private,protected失去作用,全部都是public
??有點類似C++中友元的概念
??Example
??類TMan和此函數在同一個單元
??procedure?TForm1.Button1Click(Sender:?TObject);
??var
????APerson:TMan;
??begin
????TMan.Sing;?
????APerson.FAge:=10;//雖然FAge是private?,但是此處確可以訪問??
????APerson:=TMan.Create;
????APerson.Name:='小李';
????APerson.SayHello('?是一名中國人');
??end;?

<<Delphi面向對象編程>>讀書筆記之二
<1>什么是對象
?A.對象是一組相關代碼和數據的組合.面向對象程序設計中,過程(函數)被成為方法,數據被稱做屬性(注意此處的屬性和類中property不是一回事)
?B.對象之間可以通過發送消息請求而互相聯系,一個消息通常由三部分組成:接收對象的名字,對象成員的名字(方法和property),對象成員的參數
?C.對象是有類型的,不同的對象是屬于不同的類型.

?

轉載于:https://www.cnblogs.com/stevenlaz/p/3166406.html

總結

以上是生活随笔為你收集整理的Delphi中静态方法重载还是覆盖的讨论的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。