Delphi的OverRide、OverLoad和Virtual方法

1.)方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。

  如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。

  如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

2.)Delphi 的函数覆盖(Override)与重载(overload)

  而Delphi 就是用override 关键字来说明函数覆盖的。被覆盖的函数必须是虚(virtual)的,或者是动态(dynamic)的,也就是说该函数在声明时应该包含这两个指示字中的一个,比如:

procedure Draw; virtual;

在需要覆盖的时候,只需要在子类中用override 指示字重新声明一下就可以了。

procedure Draw; override;

3.)virtual 虚类型

dynamic 动态

overload 重载

override 重写

4.)关于方法定义关键字的说明:

  在过程定义声明时包括了的关键字的含义:

static 表示是静态方法;静态方法是方法的缺省类型,不能被覆盖;

virtual 表示是虚拟方法;

dynamic 表示是动态方法;

  这两类方法的共同点是都可以被覆盖(override),区别仅在于运行时调用方法时的派发机制,virtual方法为执行速度做了优化,而dynamic方法则为代码大小做了优化;经常被覆盖的方法应该定义为virtual方法;  

message 表示是消息处理方法;在关键字message后面的值指明了这个方法要响应的消息;用消息处理方法来响应Windows的消息,这样就不用直接来调用它;

override 表示是覆盖方法;要求祖先类中必须有该方法的定义,并且参数的顺序和类型及返值的类型必须匹配;用于扩展祖先类中的该方法而不是取代它(如不调用祖先类中的该方

法则等同于取代);

overload 表示是重载方法;用于一个类中有许多同名的方法带着不同的参数表的情形;(属性的读写方法不能被重载);

abstract 表示是抽象方法;是没有实现的方法,并且必须是virtual或dynamic方法,即

在abstract前面必须有virtual或dynamic关键字,其实现部分在派生类中;如

procedure DoSomething; virtual; abstract;

reintroduce表示是重新声明的方法;用于方法的名称与祖先类中的某个方法名称相同的情形;

5.)virtual 和 dynamic定义的虚函数,都是为了子类override用的,只不过它们的实现不一样。vitrual 占用的空间大点,但速度快些。dynamci正好相反.

程序如下:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Memo1: TMemo;

private

procedure wmCopyData(var AMessage: TMessage); message WM_COPYDATA;

protected

procedure WndProc(var AMessage: TMessage); override;

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WndProc(var AMessage: TMessage);

begin

...

...

inherited WndProc(AMessage);

end;

procedure TForm1.wmCopyData(var AMessage: TMessage);

var

pdsData: PCopyDataStruct;

sGot : AnsiString;

begin

inherited;

pdsData := PCopyDataStruct(AMessage.lParam);

sGot := StrPas(pdsData^.lpData);

SendMessage(hPartner, wm_Response, Self.Handle, id_GotData);

end;

end.

在上面程序中各位朋友注意了

过程wmCopyData(var AMessage: TMessage); message WM_COPYDATA;在声明中未加任何说明即意味着是替换其父类的方法,其父类wnCopyData已不存在。而过程WndProc(var AMessage: TMessage); override;在声明中加入了override超越的说明即意味着是扩展以前的方法也就是保留了父类的方法并在其基础上增加了某些功能;

按照这样的理解,那么我例中的wmCopyData方法就应该是用现在的新wmCopyData替换掉父类的wmCopyData方法,而在本例中的wmCopyData的过程中又加入了一句inherited即继承又是何意,是否意味着新的wmCopyData方法并没有替换掉父类的wmCopyData方法?

这是message关键字的功劳. 所以不需要加override也能调用原先的处理过程

(其实都是替换了,wndproc, message中的inherited相当于callwindowproc)


TClass1 = class

procedure func1; virtual;//virtual;这个是做什么的

end;

TClass2 = class(TClass1)

procedure func1; override;//override这个是做什么的

end;

virtual 的作用就是允许Tclass1的子类也可以有fun1的过程定义.

override 的作用就是告诉tclass1在子类(tclass2)中重新定义了fun1过程.

具体运行的时候,

a: tclass1 ;

b: tclass2 ;

a.fun1 调用 tclass1的 fun1

b.fun1 调用 tclass2的 fun2

1). virtual翻译过来就是虚方法,它自已可以实现也可以不实现,主要给后代一个可以override的方法。以便子类和父类用相同的函数下实现不同的功能。

2). override就是子类用相同的函数名来做和父类不同的事,但不覆盖父类方法,(还可以继承父类的方法)函数名相同而不带override字样的函数不同。

1.)方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。

  如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。

  如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

2.)Delphi 的函数覆盖(Override)与重载(overload)

  而Delphi 就是用override 关键字来说明函数覆盖的。被覆盖的函数必须是虚(virtual)的,或者是动态(dynamic)的,也就是说该函数在声明时应该包含这两个指示字中的一个,比如:

procedure Draw; virtual;

在需要覆盖的时候,只需要在子类中用override 指示字重新声明一下就可以了。

procedure Draw; override;

3.)virtual 虚类型

dynamic 动态

overload 重载

override 重写

4.)关于方法定义关键字的说明:

  在过程定义声明时包括了的关键字的含义:

static 表示是静态方法;静态方法是方法的缺省类型,不能被覆盖;

virtual 表示是虚拟方法;

dynamic 表示是动态方法;

  这两类方法的共同点是都可以被覆盖(override),区别仅在于运行时调用方法时的派发机制,virtual方法为执行速度做了优化,而dynamic方法则为代码大小做了优化;经常被覆盖的方法应该定义为virtual方法;  

message 表示是消息处理方法;在关键字message后面的值指明了这个方法要响应的消息;用消息处理方法来响应Windows的消息,这样就不用直接来调用它;

override 表示是覆盖方法;要求祖先类中必须有该方法的定义,并且参数的顺序和类型及返值的类型必须匹配;用于扩展祖先类中的该方法而不是取代它(如不调用祖先类中的该方

法则等同于取代);

overload 表示是重载方法;用于一个类中有许多同名的方法带着不同的参数表的情形;(属性的读写方法不能被重载);

abstract 表示是抽象方法;是没有实现的方法,并且必须是virtual或dynamic方法,即

在abstract前面必须有virtual或dynamic关键字,其实现部分在派生类中;如

procedure DoSomething; virtual; abstract;

reintroduce表示是重新声明的方法;用于方法的名称与祖先类中的某个方法名称相同的情形;

5.)virtual 和 dynamic定义的虚函数,都是为了子类override用的,只不过它们的实现不一样。vitrual 占用的空间大点,但速度快些。dynamci正好相反.

程序如下:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Memo1: TMemo;

private

procedure wmCopyData(var AMessage: TMessage); message WM_COPYDATA;

protected

procedure WndProc(var AMessage: TMessage); override;

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WndProc(var AMessage: TMessage);

begin

...

...

inherited WndProc(AMessage);

end;

procedure TForm1.wmCopyData(var AMessage: TMessage);

var

pdsData: PCopyDataStruct;

sGot : AnsiString;

begin

inherited;

pdsData := PCopyDataStruct(AMessage.lParam);

sGot := StrPas(pdsData^.lpData);

SendMessage(hPartner, wm_Response, Self.Handle, id_GotData);

end;

end.

在上面程序中各位朋友注意了

过程wmCopyData(var AMessage: TMessage); message WM_COPYDATA;在声明中未加任何说明即意味着是替换其父类的方法,其父类wnCopyData已不存在。而过程WndProc(var AMessage: TMessage); override;在声明中加入了override超越的说明即意味着是扩展以前的方法也就是保留了父类的方法并在其基础上增加了某些功能;

按照这样的理解,那么我例中的wmCopyData方法就应该是用现在的新wmCopyData替换掉父类的wmCopyData方法,而在本例中的wmCopyData的过程中又加入了一句inherited即继承又是何意,是否意味着新的wmCopyData方法并没有替换掉父类的wmCopyData方法?

这是message关键字的功劳. 所以不需要加override也能调用原先的处理过程

(其实都是替换了,wndproc, message中的inherited相当于callwindowproc)


TClass1 = class

procedure func1; virtual;//virtual;这个是做什么的

end;

TClass2 = class(TClass1)

procedure func1; override;//override这个是做什么的

end;

virtual 的作用就是允许Tclass1的子类也可以有fun1的过程定义.

override 的作用就是告诉tclass1在子类(tclass2)中重新定义了fun1过程.

具体运行的时候,

a: tclass1 ;

b: tclass2 ;

a.fun1 调用 tclass1的 fun1

b.fun1 调用 tclass2的 fun2

1). virtual翻译过来就是虚方法,它自已可以实现也可以不实现,主要给后代一个可以override的方法。以便子类和父类用相同的函数下实现不同的功能。

2). override就是子类用相同的函数名来做和父类不同的事,但不覆盖父类方法,(还可以继承父类的方法)函数名相同而不带override字样的函数不同。