虚拟方法virtual的用法
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TFather = class
public
procedure Fa; // virtual;
end;
TChild = class(TFather)
public
procedure Fa; // override;
procedure Ca;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TChild }
procedure TChild.Ca;
begin
ShowMessage('Childer');
end;
procedure TChild.Fa;
begin
// inherited;
end;
{ TFather }
procedure TFather.Fa;
begin
ShowMessage('Father');
end;
procedure TForm1.Button1Click(Sender: TObject); // C->F
var
F: TFather;
begin
F := TChild.Create;
F.Fa;
// F.Ca; //编译不过去
end;
procedure TForm1.Button2Click(Sender: TObject); // C(F)
var
F: TFather;
begin
F := TFather.Create;
TChild(F).Fa; //*** 声明方法时,如果不用 virtual 和 override 关键字修饰的话
//*** 那么在子类实现时要手动的调用 inherited 才可以正确调用父
//*** 类实现的方法,但是如果使用了 virtual 和 override 的话,
//*** 则可以不用手动的调用 inherited 也能正确调用(即当按Ctrl+C
//*** 时会自动添加inherited。
TChild(F).Ca; //虽然创建的是父类,但是强制转换后(重新设定对象范围)可以调用。
//但是不确定是否会有意外的错误发生。
//如果使用了关键字override,编译器会使用晚帮定,即到运行是根据实
//际的对象来决定调用父类方法还是子类方法
//换句话说就是使用了关键字的话,强制转换将不起作用。(起到的作用
//只是检测到父类中是否有此方法了,有可以调用,但是调用的还是子类
//的方法,要是没有就根本不能调用)
end;
procedure TForm1.Button3Click(Sender: TObject); // F(C)
var
C: TChild;
begin
C := TChild.Create;
TFather(C).Fa;
//TFather(C).Ca; //编译不过去
end;
end.