对象的方法能定义成静态(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表示是重新声明的方法;用于方法的名称与祖先类中的某个方法名称相同的情形)

Delphi 中同类型方法的说明的更多相关文章

  1. DELPHI中枚举类型数据的介绍和使用方法

    在看delphi程序的时候看到aa=(a,b,c,d);这样的东西,还以为是数组,同事说是函数,呵呵,当然这两个都不屑一击,原来这样式子是在声明并付值一个枚举类型的数据.下边写下来DELPHI中枚举类 ...

  2. delphi 中TStringList Clear 方法的时候该对象有没有被释放

    delphi 中TStringList 通过function AddObject(const S: string; AObject: TObject): Integer; 方法添加了一个对象,请问我在 ...

  3. Delphi中String类型原理介绍

    Delphi中字符串的操作很简单,但幕后情况却相当复杂.Pascal传统的字符串操作方法与Windows不同,Windows吸取了C语言的字符串操作方法.32位Delphi中增加了长字符串类型,该类型 ...

  4. JavaScript中Array类型方法总结

    Array类型是ECMAScript中最常用的类型之一,ECMAScript中的数组与其他多数语言中的数组有着相当大的区别.ECMAScript数组的每一项可以保存任何类型的数据.这里总结了数组类型的 ...

  5. Delphi中返回类型为string的函数的一个陷阱(不是很懂)

    如果类的一个成员函数的返回值是string类型,需要注意一个问题 其返回值可能是错误的 例如函数的实现如下 function GetString( s: string ): string;begin  ...

  6. delphi中无类型文件读写

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  7. Delphi中MD5实现方法(转)

    原来写过一个计算MD5的程序,是用了一个叫MD5.pas的单元,使用起来还算简单,但还有更简单的办法,安装了indy就会有IdHashMessageDigest单元(delphi 7默认安装indy) ...

  8. Delphi 中记录类型 给记录指针赋值。

    PPersion=^TPersion;  TPersion=packed record     Name:string;     Sex:string;     Clasee:string;  end ...

  9. Delphi中WideString类型如何转化成String类型

    var wstr:WideString; str:string; begin str:=WideCharToString(PWideChar(wstr)); end;

随机推荐

  1. 学习ceph官网的ceph块设备命令(一)

    一)存储池命令 1.列出存储池 #ceph osd lspools #ceph osd pool ls 2.创建存储池 # ceph osd pool create yhcpool 512 pool ...

  2. Swift高级语法学习总结(转)

    Swift高级语法学习总结 1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参 ...

  3. 阅读笔记 火球——UML大战需求分析 2

    从大一一开始接触C++的时候,上课模模糊糊的听王辉老师讲,我们第一学期学的是面向过程,第二学期学的是面向对象,迷迷糊糊的上了一年,到了大二的时候,对这个面向什么没有什么深层次的理解.知道学了JAVA ...

  4. 什么是hasLayout?

    想更好的理解CSS,尤其是IE下对CSS的渲染,hasLayout是一个非常有必要彻底弄清楚的概念,大多数IE下的显示错误,就是源于hasLayout.hasLayout是一种只读属性,有两种状态tr ...

  5. GOLANG 基本数据类型 整型

    基本数据类型-整型 种类     有符号(负号)      int8 int16 int32 int64 无符号(无符号) uint8 uint16 uint32 uint64 架构特定(取决于系统位 ...

  6. 微信小程序-视图数据绑定

    数据绑定 在逻辑层设置数据例如: Page({ data: { message: 'Hello MINA!' } })//设置了一个属性,名称是message 值为Hello MINA! 在视图显示数 ...

  7. TFS二次开发系列:六、TFS的版本控制

    在TFS中对于版本控制是在WorkSpace工作区来控制的. 首先我们先整理WorkSpace的一些基本使用方法. CheckIn:迁入挂起的操作 CreateMapping:创建一个本地映射地址 D ...

  8. angularjs指令系统系列课程(3):替换replace,内容保留transclude,作用方式restrict

    这一节我们主要看一下replace,transclude,restrict这三个参数 1.replace 可取值:bool 默认为:true 对于replace属性,设置为false表示原有指令标识不 ...

  9. Loading加载小插件,用户可以选择html格式或canvas格式,自定义loading图片,canvas色彩搭配可根据个人喜好

    ;(function($) { $.Loading = function(options) { //暴漏插件默认值 $.Loading.defaults = { speed: 200, //弹出层淡出 ...

  10. cordova 下载更新

    function UpdateForAndroid(downloadUrl) { $ionicLoading.show({ template: "已经下载:0%" }); var ...