Go homepage(回首页)
Upload pictures (上传图片)
Write articles (发文字帖)

The author:(作者)aaa
published in(发表于) 2014/7/19 0:12:32
delphi类中的方法是用实例-方法

delphi类中的方法是用实例|方法|详解

方法

方法是属于一个给定对象的过程和函数,方法反映的是对象的行为而不是数据,刚才提到了对象的两个重要的方法即构造器和析构方法。为了使对象能执行各种功能,所以能在对象中定制方法。

1.方法的类型

对象的方法能定义成静态(Static)、虚拟(Virtual)、动态(Dynamic)或消息处理(Message)。

请看下面的例子:

Tfoo=class

Procedure IamAStatic;

Procedure IamAVitual;virtual;

Procedure IamADynamic;dynamic;

Procedure IamAMessage(var M:TMessage);message wm_SomeMessage;

end;

(1)静态方法

IAmAStatic 是一个静态方法。静态方法是方法的默认类型,它可以像通常的过程和函数那样被调用。编译器知道这些方法的地址,所以调用一个静态方法时它能把运行信息静态地链接到可执行文件。静态方法执行的速度最快,但它们却不能被覆盖来支持多态性。

(2)虚拟方法

IAmAVirtual 是一个虚拟方法。虚拟方法和静态方法的调用方式相同。由于虚拟方法能被覆盖,在代码中调用一个指定的虚拟方法时编译器并不知道它的地址,因此编译器需要通过建立虚拟方法表(VMT)来查找在运行时的函数地址。所有的虚拟方法在运行时通过VMT 来调度,一个对象的VMT表中除了自己定义的虚拟方法外,还有它的祖先的所有虚拟方法,因此虚拟方法占用的内存要比较多,但它执行得更快。

(3)动态方法

IAmADynamic 是一个动态方法。动态方法跟虚拟方法基本相似,只是它们的调度系统不同。编译器为每一个动态方法指定一个独一无二的数字,用这个数字和动态方法的地址构造一个动态方法表(DMT)。不像VMT 表,在DMT 表中仅有它声明的动态方法,并且这个方法需要祖先的DMT 表来访问它其余的动态方法。正因为这样,动态方法比虚拟方法用的内存要少,但执行起来较慢,因为有可能要到祖先对象的DMT 中查找动态方法。

(4)消息处理方法

IAmAMessage 是一个消息处理方法。在关键字Message 后面的值指明了这个方法要响应的消息。

用消息处理方法来响应Windows 的消息,这样就不用直接来调用它。

(5)方法的覆盖

在Object Pascal 覆盖一个方法用来实现OOP 的多态性概念。通过覆盖,使这一方法在不同的派生类间表现出不同的行为。Object Pascal 中能被覆盖的方法是在声明时被标识为Virtual 或Dynamic 的方法。为了覆盖一个方法,在派生类的声明中用Override 代替Virtual 或Dynamic。

例如用下面的代码覆盖IAmAVirtual 和IAmADynamic 方法:

TfooChild=class(TFoo)

Procedure IamAVitual;override;

Procedure IamADynamic;override;

Procedure IamAMessage(var M:TMessage);message wm_SomeMessage;

end;

用了Override 关键字后,编译器就会用新的方法替换VMT 中原先的方法。如果用Virtaul 或Dynamic 替换Override 重新声明IAmAVirtual 和IAmADynamic,将是建立新的方法而不是对祖先的方法进行覆盖。同样,在派生类中如果企图对一个静态方法进行覆盖,在新对象中的方法完全替换在祖先类中的同名方法。

(6)方法的重载

就像普通的过程和函数,方法也支持重载,使得一个类中有许多同名的方法带着不同的参数表,能重载的方法必须用Overload 指示符标识出来,可以不对第1 个方法使用Overload。

下面的代码演示了一个类中有3 个重载的方法:

type

TSomeClass=class

Procedure Amethod(I:integer);overload;

Procedure Amethod(S:string);overload;

Procedure Amethod(D:double);overload;

end;

(7)重新引入方法名称

有时候,需要在派生类中增加一个方法,而这个方法的名称与祖先类中的某个方法名称相同。在这种情况下,没必要覆盖这个方法,只要在派生类中重新声明这个方法即可。但在编译时,编译器就会发出一个警告,提示派生类的方法将隐藏祖先类的同名方法。要解决这个问题,可以在派生类中使用Reintroduce 指示符,下面的代码演示了Reintroduce 指示符的正确用法:

type

TSomeBase=class

Procedure A;

end;

TSomeClass=class

Procedure A;reintroduce;

end;

(8)Self

在所有对象的方法中都有一个隐含变量称为Self,Self 是用来调用方法的指向类实例的指针。Self由编译器作为一个隐含参数传递给方法。




If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)





QQ:154298438
QQ:417480759