一、
1.类的虚方法(virtual)和动态方法(dynamic)
方法的定义:
- TMyClass = class
- procedure Proc1(x,y: Real); virtual; //虚方法
- function Fun1(x,y: Real): Real; virtual;
- procedure Proc2(x,y: Real); dynamic; //动态方法
- function Fun2(x,y: Real): Real; dynamic;
- end;
在子类中要实现父类的方法,就必须加上override,例如:
- TBass = class
- procedure Proc(x,y: Real); virtual;
- function Fun(x,y: Real): Real; dynamic;
- end;
- TChild = class(TBass)
- procedure Proc(x,y: Real); override;
- function Fun(x,y: Real): Real; override;
- end;
虚方法和动态方法的区别。
每个类都内含着两个表: 虚方法表(VMT)和动态方法表(DMT):
1.1 VMT 表包含着本类与其所有父类的虚方法 - 那一般会是一个比较庞大的表;
1.2 DMT 表只包含本类的动态方法 - 如果要调用其上层类的动态方法, 只能逐级查找;
因此,使用虚方法速度上会有优势(是实现多态行为的最有效的实现方式),使用动态方法会节约内存(大量要被许多派生类继承的方法、但只是偶尔才覆盖)。
reintroduce(重新引入):当隐藏一个先前声明的虚方法时,不给出警告信息(要使用新方法隐藏继承下来的虚方法)。
2.类的静态方法
静态方法是默认的,如果不是虚方法(virtual)或者纯虚方法,则它就是静态方法。静态方法就是给类属性来调用的,它可以存在于私有区。例如:
- TMyClass = class(TObject)
- private
- class var FName: string;
- class procedure SetName(const Value: string); static; {静态类方法又多了一个 static 指示字}
- published
- class property Name: string read FName write SetName;
- end;
3.类的类方法。
类方法是通过类名就可以访问的方法。类方法不能在private 和 protected 区;类方法不能是虚方法;类方法只能使用类中的、在对象实例化以前的数据。
3.1 类方法的定义
- TMyClass = class(TObject)
- class procedure alert(s:string);
- end;
3.2 类方法的实现与其他方法的实现类似
3.3 类方法的调用
类方法的调用可以通过两种方式来调用:1是通过类名.方法的形式,例如TMyClass.alert();2.是通过类的对象名来进行调用
4.抽象方法
抽象方法是为了实现接口的功能而存在的,抽象方法是一个虚方法或者动态方法,也叫纯虚方法。抽象方法在本类中只有定义、没有实现;方法是在子类中实现。如果一个类中有抽象方法,那么该类就为抽象类,抽象类只能通过子类来实例化。最典型的抽象类是TString,其实例化需要用TStringList来实现。在Delphi7及其以前的版本中,我们需要通过查看类中是否包含抽象方法来判断这个类是否为抽象类。
4.1 抽象方法的定义
- TMyClass = class(TObject)
- procedure Proc1; virtual; abstract; {抽象方法首先应该是一个虚方法或动态方法}
- function Fun: string; dynamic; abstract; {抽象方法也叫纯虚方法}
- end;
4.2 抽象方法的实现
抽象方法的实现与实现虚方法或者动态方法一致,通过覆盖(Override)指示字来实现。
5.如果带有sealed和final指示字的方法,是无法被继承和覆盖的。
二、
1.构造方法和析构方法
我们都知道,构造方法是用来创建和初始化一个实例对象的方法;析构方法是在对象销毁时调用并释放内存。例如:
- TMyClass = class(TObject)
- public
- constructor Create; {构造方法}
- destructor Destroy; override; {析构方法}
- end;
必须使用constructor和destructor来定义,其实现如下:
- constructor TMyClass.Create;
- begin
- inherited;
- //...
- end;
- destructor TMyClass.Destroy;
- begin
- //...
- inherited;
- end;
这里,create是用的最多的方法,而Destory则是用的最少的方法,因为系统已经为我们定义了Free方法来处理,这比单单用Destory会更安全。
要调用构造或者析构函数,必须使用一个实例对象的引用:
- MyObject.Destroy;
2.消息方法
我们先来看一下消息方法的定义:用来响应动态分派的消息。
- procedure KeyDown(var msg:TWMKeyDown);message WM_KEYDOWN;
消息方法与其他方法的不同在于,其后多了一个message指示字,后面是拦截的消息名称WM_KEYDOWN。
消息方法的实现
- procedure TForm1.KeyDown(var msg: TWMKeyDown);
- begin
- if Chr(Message.CharCode) = #13 then
- Self.Text := Char(msg.CharCode);
- end;
消息方法与事件方法如在同一个窗体中,消息方法会拦截事件方法。如需要事件方法和消息方法都能执行,则可以按如下操作:
- {把消息的实现改为:}
- procedure TForm1.KeyDown(var msg: TWMKeyDown);
- begin
- ShowMessage('消息: ' + Char(msg.CharCode));
- inherited;
- end;
- {会先执行消息, 后调用方法}
- {把消息的实现改为:}
- procedure TForm1.KeyDown(var msg: TWMKeyDown);
- begin
- inherited;
- ShowMessage('消息: ' + Char(msg.CharCode));
- end;
- {会先调用方法, 后执行消息}
3.方法的调用约定
Delphi默认对参数的读取是从左到右,Window API是从右到左。