方法是属于一个给定对象的过程和函数,方法反映的是对象的行为而不是数据,前一篇提到的对象的两个重要的方法:构造方法和析构方法。

  为了使对象能执行各种功能,你能在对象中定制方法

  创建一个方法用两个步骤,首先在对象类型的声明中声明这个方法。然后再用代码定义方法。下面的代码就演示了声明和定义一个方法的步骤

type
TBoogieNights = class
Dance: Boolean;
Procedure DoTheHustle;
end; procedure TBoogieNights.DoTheHustle;
begin
Dance:= True;
end;

  注意:在定义方法体时,必须使用完整的名字,就像在定义方法DoTheHustle时那样。同时也要注意到,这个方法中,对象的Dance域能够被直接访问

一、方法的类型

  对象的方法能定义成静态(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消息,这样就不用直接来调用它

补充:关键字Class

  在一个类的方法前面加上关键字class,使得方法向其它通常的过程和函数一样调用而不需要生成一个包好这个方法的类的实例,这个功能是从C++的Static函数借鉴来的。

  要小心:不要让一个类方法依赖于任何实例信息,否则编译时将出错

  

二、方法的覆盖

  在Delphi覆盖一个方法用来实现OOP的堕胎性概念。通过覆盖使一种方法在不同的派生类间表现出不同的行为。Delphi中能被覆盖的方法是在声明时被标识为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,将是建立新的方法而不是对祖先的方法进行覆盖。

  同样,在派生类中如果企图对一个静态方法进行覆盖,在新对象中的方法完全替换在祖先类中的同名方法

三、方法的重载

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

type
TSomeClass = class
procedure AMethod(I: Integer); overload;
procedure AMethod(S: String); overload;
procedure AMethod(D: Double); overload;
end;

  

四、重新引入方法名称

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

type
TSomeBase = class
procedure Cooper;
end; TSomeClass = class(TSomeBase)
procedure Cooper; reintroduce;
end;

  

五、Self

  在所有对象的方法中都有一个隐含变量称为Self,Self是用来调用方法的指向类实例的指针。

  Self由编译器作为一个隐含参数传递给方法

Delphi面向对象的方法的更多相关文章

  1. delphi cxgrid 使用方法

    delphi cxgrid 使用方法1.绑定数据 方法 cxGrid1DBTableView1.DataController.DataSource:=DataSource12.去掉"Drag ...

  2. js面向过程改写成面向对象--通用方法

    响亮的标题:一个万能的,保底的.面向过程改写成面向对象的方法 前提朗读:很多刚接触js面向对象的时候都不知道如何能快速的写出一个面向对象的程序,这个是必然的现象,不是每一位学js的一上来就会写面向对象 ...

  3. js面向对象+一般方法的选项卡

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Delphi基本图像处理方法汇总

    这篇文章主要介绍了Delphi基本图像处理方法,实例汇总了Delphi操作图像实现浮雕.反色.模糊.翻转等常用效果的方法,非常具有实用价值,需要的朋友可以参考下   本文实例汇总了Delphi基本图像 ...

  5. PHP面向对象-----魔术方法

    PHP面向对象-----魔术方法 __get($name)--触发时机:当调用一个不访问的成员属性的时候,会自动触发,可以利用这个方法来完成对不可调用的属性进行调用,但是不能设置值 ___set($n ...

  6. 买了本Delphi面向对象编程思想,正在看,产生些问题。

    1:第33页说,Delphi通过调用类的一个构造函数来建立一个对象的实例,对象至少有一个create()的构造函数,使用时候写MyObject:=TmyObject.create即可.   但是第37 ...

  7. CMM模型,结构化开发方法和面向对象开发方法的比较,UML(统一建模语言),jackson开发方法

    CMM模型 一.CMM简介 CMM,英文全称为Capability Maturity Model for Software,即:软件成熟度模型. CMM的核心是把软件开发视为一个过程.它是对于软件在定 ...

  8. Delphi中匿名方法动态绑定事件

    应恢弘之约,写了一个对其发布的匿名函数动态绑定到事件的封装,代码如下: type TAnonEvent=class public class function Wrap<T1,T2>(On ...

  9. javaScript面向对象继承方法经典实现

    转自原文javaScript面向对象继承方法经典实现 JavaScript的出现已经将近20多年了,但是对这个预言的褒贬还是众说纷纭.很多人都说JavaScript不能算是面向对象的变成语言.但是Ja ...

随机推荐

  1. 一、 Java的值传递和引用传递

    如果参数类型是原始类型(基本类型),那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的.如果在函数中改变了副本的值不会改变原始的值. 如果参数类型是引用类型,那么 ...

  2. 23 使用环境 UsageEnvironment——Live555源码阅读

    23 使用环境 UsageEnvironment——Live555源码阅读(三)UsageEnvironment 23 使用环境 UsageEnvironment——Live555源码阅读(三)Usa ...

  3. 将Apache加入到linux系统service

    将Apache加入到linux系统service 将apache加入到linux系统服务,用service命令来控制apache的启动和停止. 本文由乌合之众瞎写http://www.cnblogs. ...

  4. php构造函数和析构函数

    构造函数 void __construct ([ mixed $args [, $... ]] ) PHP 5 允行开发者在一个类中定义一个方法作为构造函数.具有构造函数的类会在每次创建新对象时先调用 ...

  5. freemodbus-v1.5.0 源码分析

    注:转载请注明出处   http://www.cnblogs.com/wujing-hubei/p/5935142.html FreeModbus协议栈作为从机,等待主机传送的数据,当从机接收到一帧完 ...

  6. 用Java计算某个日期100天后的日期

    用Java计算日期时间,首先考虑到时间类,Java中提供的和时间日期相关的类里,有一个Calendar类,可以获取某个时间日期. 计算某个日期100天后的日期,思路如下: 1.先设定时间,例如2017 ...

  7. SELinux的关闭与开启

    SELinux是美国国家安全局对于强制访问控制的实现,是NSA在Linux社区的帮助下开发的一种访问控制体系,所以SELinux可以看做是安全强化的Linux子系统,和防火墙有相似点,作用之一是保证计 ...

  8. ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)

    判别MST是否唯一的例题. POJ1679-The Unique MST 题意:给定图,求MST(最小生成树)是否唯一,唯一输出路径长,否则输出Not Unique! 题解:MST是否唯一取决于是否有 ...

  9. 3. javacript高级程序设计-基本概念

    1.1 语法 ECMAScript借鉴了C和其他类C语言的语法 1.1.1 区分大小写 ECMAScript中的一切(变量,函数和操作符)都是区分大小写的,变量test和Test是不同的变量 1.1. ...

  10. pt-query-digest使用介绍【转】

    本文来自:http://isadba.com/?p=651 一.pt-query-digest参数介绍. pt-query-digest --user=anemometer --password=an ...