Delphi中静态方法重载还是覆盖的讨论
Delphi中靜態(tài)方法重載還是覆蓋的討論
新人學習Delphi的時候,容易搞不懂的一個問題,當子類方法和基類方法同名,并且參數(shù)也一樣的時候,叫做什么呢?是覆蓋,還是重載呢?
?
答案是隱藏父類方法。
?
一般我們的理解重載是同名,不同參數(shù)的同一個類里面實現(xiàn),
或者父類和子類方法同名,參數(shù)不同,子類必須有overide關(guān)鍵字,表示重載方法。
?
也就是說重載必須有overload修飾;
?
覆蓋呢?覆蓋必須有override修改;
?
否則同名,同參數(shù)就是隱藏方法。
=================================================================
下面是筆者自己的程序,您可以嘗試一下。
?
program?Project2;
?
{$APPTYPE?CONSOLE}
?
uses
??SysUtils;
?
??type?tclassa=class
?????private
???????age?:Integer;
?????public
???????function?getage:integer;???//靜態(tài)方法
???????function?getDat:integer;??//靜態(tài)方法
???????end;
?
???????tclassb=class(tclassa)
???????private
?
?????????public
???????????function?getdat:integer;??//隱藏靜態(tài)方法
???????????function?getage:Integer;?//隱藏靜態(tài)方法
???????????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());?//?調(diào)用的是子類的隱藏后的靜態(tài)方法?
?
??readln;
?
??readln;
??a.free;
??b.free;
?
??{?TODO?-oUser?-cConsole?Main?:?Insert?code?here?}
end.
?
我們可以看到隱藏了父類方法之后,還是可以調(diào)用父類同名方法的。這就和覆蓋是相似的。
?
?
參考資料
=================================
?
Delphi面向?qū)ο蠓椒ǖ姆诸愐约案采w隱藏和重載
<6>?方法的分類
??按用途分?普通方法,構(gòu)造方法,析構(gòu)方法,?類方法,消息處理方法
??按運行綁定機制分:靜態(tài)方法,虛方法,動態(tài)方法,[注意此處的靜態(tài)方法不是所謂的class?method?而是普通的方法?,靜態(tài)是指靜態(tài)編譯]
??關(guān)于析構(gòu)方法,最好是用名字destroy?,這樣可以使用Free方法,而不要直接調(diào)用destroy方法.
??Free方法會先判斷對象變量是否為nil.
??procedure?TObject.Free;
??begin
????if?Self?<>?nil?then
??????Destroy;
??end;
??
??消息處理方法的例子:
??procedure?WMChar(var?message:TWMChar);message?WM_CHAR;
??問題來了.為什么在一個Control中聲明了消息處理方法,就能調(diào)用此消息處理方法呢,這里涉及到
??TObject?中Dispatch方法的秘密,我暫時沒有看懂.留作以后繼續(xù)學習
??先給出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;
??隱藏是子類中的方法和父類的方法同名,而且參數(shù)相同,沒有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('是一名中國人');?
?????//注意了此處調(diào)用的是父類的TMan.Sayhello方法
?????//
?????ChinesePerson:=TChinesePerson.Create;
?????ChinesePerson.SayHello('是一名中國人');?//此時調(diào)用的是TChineseMan.sayHello
?????
?????//如果想要APerson調(diào)用TChineseMan.sayHello方法?應(yīng)該采取強制類型轉(zhuǎn)換,強制類型轉(zhuǎn)換其實就是對象框架的范圍調(diào)整
?????TChinesePerson(APerson).SayHello('是一名中國人');?//此時調(diào)用的是TChineseMan.sayHello?????
????end;
????
<8>??可見性
??Delphi中四種類成員的保護方式:published,public,protected,private;???
??published,public?是可以最大訪問,protected是對之類是可見的,private是對子類不可見
??另外對象變量如果與其類的聲明在同一個單元中,則private,protected失去作用,全部都是public
??有點類似C++中友元的概念
??Example
??類TMan和此函數(shù)在同一個單元
??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面向?qū)ο缶幊?gt;>讀書筆記之二
<1>什么是對象
?A.對象是一組相關(guān)代碼和數(shù)據(jù)的組合.面向?qū)ο蟪绦蛟O(shè)計中,過程(函數(shù))被成為方法,數(shù)據(jù)被稱做屬性(注意此處的屬性和類中property不是一回事)
?B.對象之間可以通過發(fā)送消息請求而互相聯(lián)系,一個消息通常由三部分組成:接收對象的名字,對象成員的名字(方法和property),對象成員的參數(shù)
?C.對象是有類型的,不同的對象是屬于不同的類型.
?
轉(zhuǎn)載于:https://www.cnblogs.com/stevenlaz/p/3166406.html
總結(jié)
以上是生活随笔為你收集整理的Delphi中静态方法重载还是覆盖的讨论的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谁在刀尖舔血?美股科技股崩盘式暴跌,三倍
- 下一篇: dataset string datas