virtural表示该方法在当前类的子类中可以被重载override
如果父类已经存在同名定义方法并且被定为 virtural,则子类定义时,如果不用 override 则表示覆盖,用 override 则表示重载。重载要求方法的参数必须与父类的一致,而覆盖则可以不同。重载和覆盖带来的结果是不一样的。举个例子:
type
TMyParent=class(TObject)
public
procedure A; Virtual;
procedure B;
end;
TMyChild1=class(TMyParent)
public
procedure A(a:integer);
end;
TMyChild2=class(TMyParent)
public
procedure A; override;
end;
procedure TMyParent.A;
begin
end;
procedure TMyParent.B;
begin
A(); //调用了A
end;
var Child1:TMyChild1;
Child2:TMyChild2;
begin
Child1:=TMyChild1.Create;
Child2:=TMyChild2.Create;
//注意 TMParent 的方法B中是调用了方法A
Child1.B(); //执行B,覆盖A,实际上调用了TMyParent的A
Child2.B(); //执行B,重载A,实际上调用了TMyChild2的A
end;
通过以上例子可以看出:
1、覆盖只是在子类中覆盖了父类的同名方法,在子类中调用这个名字的方法其实就是执行新的方法;而原来父类中所引用到的方法还是原来再父类中定义的,也就是说子类继承下来的方法如果在父类中定义调用到这个名字方法时,还是执行原来父类中定义的方法。就项Child1.B执行的还是原来TMyParent中的A。
2、重载相当于重新定义父类的方法的实现,在子类中调用这个名字的方法其实就是执行新的方法;而原来父类中所引用到的方法将以子类中定义的,就是是说子类继承下来的方法如果在父类中定义调用到这个名字方法时,则执行的将是子类中新定义的方法。就项Child2.B执行是新的 原来TMyChild2中的A。
对于 destructor destroy ,一般情况下,如果覆盖了原来的父类方法,在子类新方法中加上 inheited destroy 对于类本身应该没有什么影响。不过建议对于析构函数不要用覆盖而是要用重载,以免对于一些内部比较特殊的类会有影响(具体什么情况还想不出来,但是对于析构还是用重载比较稳妥一点)