Delphi中静态办法重载还是覆盖的评论辩论
添加时间:2013-7-2 点击量:
Delphi中静态办法重载还是覆盖的评论辩论
新人进修Delphi的时辰,轻易搞不懂的一个题目,当子类办法和基类办法同名,并且参数也一样的时辰,叫做什么呢?是覆盖,还是重载呢?
答案是隐蔽父类办法。
一般我们的懂得重载是同名,不合参数的同一个类里面实现,
或者父类和子类办法同名,参数不合,子类必须有overide关键字,默示重载办法。
也就是说重载必须有overload润饰;
覆盖呢?覆盖必须有override批改;
不然同名,同参数就是隐蔽办法。
=================================================================
下面是笔者本身的法度,您可以测验测验一下。
program Project2;
{¥APPTYPE COLE}
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+EAX2-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.对象是有类型的,不合的对象是属于不合的类型.
Delphi中静态办法重载还是覆盖的评论辩论
新人进修Delphi的时辰,轻易搞不懂的一个题目,当子类办法和基类办法同名,并且参数也一样的时辰,叫做什么呢?是覆盖,还是重载呢?
答案是隐蔽父类办法。
一般我们的懂得重载是同名,不合参数的同一个类里面实现,
或者父类和子类办法同名,参数不合,子类必须有overide关键字,默示重载办法。
也就是说重载必须有overload润饰;
覆盖呢?覆盖必须有override批改;
不然同名,同参数就是隐蔽办法。
=================================================================
下面是笔者本身的法度,您可以测验测验一下。
program Project2;
{¥APPTYPE COLE}
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+EAX2-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.对象是有类型的,不合的对象是属于不合的类型.