核心提示:dynamic就是它是动态方法,没有静态地址,所以速度慢一点 virtual是虚方法,如果在基类中不声明成虚方法的话,继承后,该方法会提示一警告信息,把基类中方法屏蔽掉了 --------------...
dynamic就是它是动态方法,没有静态地址,所以速度慢一点 virtual是虚方法,如果在基类中不声明成虚方法的话,继承后,该方法会提示一警告信息,把基类中方法屏蔽掉了
---------------------------------------------------------------
动态(Dynamic)和虚拟(Virtual)后都可以使用Override关键字在派生类中对对应方法进行覆盖从而实现多态......
虚拟方法和动态方法在语义上可以说是等价的,他们唯一的区别在于对方法调用策略的内部实现上:虚拟方法从速度最优化的角度实现代码优化,而动态方法则是从空间最优的角度实现代码优化......
被覆盖的动态方法在派生类的VMT中不再出现........所以节省空间........但查询速度慢
被覆盖的虚拟方法在怕生类的VMT中再次出现........所以查询速度快......但浪费空间
---------------------------------------------------------------
虚拟方法和动态方法
要使一个方法成为虚拟的或动态的,需要在其声明中包括指示字virtual或dynamic。虚拟方法和动态方法不同于静态方法,它们可以在其后裔类中被覆盖(overridden)。当一个覆盖方法被调用时,方法调用中使用的类或对象的实际(运行时)类型决定了哪一个实现是有效的,而非变量声明的类型决定。
要覆盖一个方法,需要在再声明中使用指示字override。一个override声明必需与其祖先声明在参数顺序和类型以及结果(如果有)等各方面匹配。
下面的例子中,TFigure中声明的Draw方法在两个后裔类中都被覆盖。
type
TFigure = class
procedure Draw; virtual;
end;
TRectangle = class(TFigure)
procedure Draw; override;
end;
TEllipse = class(TFigure)
procedure Draw; override;
end;
对于上面给出的声明,下面的代码举例说明了在运行时通过一个变量调用虚拟方法时,其类型变化的效果。
var
Figure: TFigure;
begin
Figure := TRectangle.Create;
Figure.Draw; //调用的是TRectangle.Draw
Figure.Destroy;
Figure := TEllipse.Create;
Figure.Draw; //调用的是TEllipse.Draw
Figure.Destroy;
end;
只有虚拟方法和动态方法可以被覆盖。然而,所有的方法都可以被重载(overloaded),见重载方法。
虚拟和动态
虚拟方法和动态方法在语义上是等价的。其不同之处仅在于运行时对方法调用如何实现调度。
虚拟方法在速度方面相对更优化,而动态方法在代码尺寸方面相对更优化。
一般情况下,虚拟方法是实现多种行为最有效的途径。当一个基本类声明了许多可覆盖的方法,并且在应用程序中将被许多后裔类继承但很少覆盖时,动态方法是有用的。