Delphi之virtual,dynamic,abstract

Delphi之virtual,dynamic,abstract 

对象的方法能定义成静态(static)、虚拟(virtual)、动态(dynamic)或消息处理(message)。请看下面
的例子: 

TFoo = class
procedure IAmAStatic;
procedure IAmAVirtual; 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 IAmAVirtual; override;
procedure IAmADynamic; override;
procedure IAmAMessage(var M:TMessage); message wm_SomeMessage;
end; 

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

6. 方法的重载
就像普通的过程和函数,方法也支持重载,使得一个类中有许多同名的方法带着不同的参数表,
能重载的方法必须用overload指示符标识出来,可以不对第一个方法用overload。下面的代码演示了一
个类中有三个重载的方法: 

type
TSomeClass = class
procedure AMethod(I:Integer); overload;
procedure AMethod(I:String); overload;
procedure AMethod(Iouble); overload;
end; 

7. 重新引入方法名称
有时候,需要在派生类中增加一个方法,而这个方法的名称与祖先类中的某个方法名称相同。在
这种情况下,没必要覆盖这个方法,只要在派生类中重新声明这个方法。但在编译时,编译器就会发
出一个警告,告诉你派生类的方法将隐藏祖先类的同名方法。要解决这个问题,可以在派生类中使用
reintroduce指示符,下面的代码演示了reintroduce指示符的正确用法:
type
TSomeBase = class
procedure Cooper;
end;
TSomeClass = class(TSomeBase)
procedure Cooper; reintroduce;
end; 

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

virtual, dynamic: 虚拟方法和动态方法, 在语义上是等价的, 只是前者是时间最优,后者是空间
abstract 抽象方法是那些在类中声明但未实现的虚拟方法或动态方法。
抽象方法的实现推延到后裔类中。
声明抽象方法必需在指示字virtual或dynamic之后使用abstract。
例如: procedure DoSomething; virtual; abstract;
不能调用没有实现或没有定义声明的抽象方法。 

override 重载,实现多态。实现或覆盖virtual, dynamic, abstract的声明
overload 再定义一个名称相同但参数不同的函数. (调用时自动根据参数选择) 跟class object 没有关系 

stdcall 使用标准的win32参数传递技术. 其他如register,cdecl,pascal 

message 消息处理 

(reintroduce表示是重新声明的方法;用于方法的名称与祖先类中的某个方法名称相同的情形)
时间: 2024-10-16 01:47:24

Delphi之virtual,dynamic,abstract的相关文章

virtual和abstract的区别和联系

壹. 相同 他们有些相似.有些场景用哪个都行! 1. 修饰父类.让子类重写 virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义. 2. 都用必须public 如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的.毕竟加上virtual或abstract  就是让子类重新定义的,而private成员是不能被子类访问的. 贰. 区别 但是它们的区别很大.(virtual是"虚拟的",abstract是&quo

c# 中virtual与abstract

在C#的学习中,容易混淆virtual方法和abstract方法的使用,现在来讨论一下二者的区别.二者都牵涉到在派生类中与override的配合使用. 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法. 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法.那么在对派生

virtual和abstract的区别

virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义. 它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的.毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的. 但是它们的区别很大.(virtual是“虚拟的”,abstract是“抽象的"). (1)virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不

sealed、new、virtual、abstract与override 总结

原文地址:http://www.cnblogs.com/DebugLZQ/archive/2011/08/09/2132468.html 1. sealed--"断子绝孙" 密封类不能被继承.密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写.当应用于方法或属性时,sealed修饰符必须始终与override一起使用. 即:密封类不会有子类,所以是"断子绝孙". 2. new--"你是我的,我是我的" new关键字用于显式隐藏从基

【转】C#中virtual和abstract的区别

看到一边文章中有诸多不严谨之处,转载并加以修改. C++: C++中,由virtual实现多态.除多态外,virtual有两个特殊用法: 1.虚基类(Virtual base class) 为解决多重继承时的二义性提出来的.使用方法: class B :virtual public A class C :virtual public A class D: public B, public C Abstract class 2.纯虚函数 含有纯虚函数的类叫做抽象类.纯虚函数如下: void vir

asp.net中virtual和abstract的区别分析

这篇文章主要介绍了asp.net中virtual和abstract的区别,较为详细的分析了virtual与abstract的概念与具体用法,并以实例的形式予以总结归纳,需要的朋友可以参考下 本文实例分析了asp.net中virtual和abstract的区别,分享给大家供大家参考.具体分析如下: 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况:情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例

asp.net中virtual和abstract的区别

一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况:情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法.情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法.那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法. 当一个方法被声明为Virtual时,它是一个虚拟方法,直到你使用ClassName variable =

C#中virtual和abstract的区别

virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义. 它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的.毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的. 但是它们的区别很大.(virtual是“虚拟的”,abstract是“抽象的"). (1)virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不

.NET virtual和abstract的区别和联系

1. 相同他们有些相似.有些场景用哪个都行!1. 修饰父类.让子类重写virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义. 2. 都用必须public如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的.毕竟加上virtual或abstract 就是让子类重新定义的,而private成员是不能被子类访问的. 2. 区别但是它们的区别很大.(virtual是“虚拟的”,abstract是“抽象的”).1. 必须实现.