help里的说明 Static methodsMethods are by default static. When a static method is called, the declared (compile-time) type of the class or object variable used in the method call determines which implementation to activate. In the following example, the Draw methods are static.type TFigure = class procedure Draw; end; TRectangle = class(TFigure) procedure Draw; end;Given these declarations, the following code illustrates the effect of calling a static method. In the second call to Figure.Draw, the Figure variable references an object of class TRectangle, but the call invokes the implementation of Draw in TFigure, because the declared type of the Figure variable is TFigure.var Figure: TFigure; Rectangle: TRectangle; begin Figure := TFigure.Create; Figure.Draw; // calls TFigure.Draw Figure.Destroy; Figure := TRectangle.Create; Figure.Draw; // calls TFigure.Draw TRectangle(Figure).Draw; // calls TRectangle.Draw Figure.Destroy; Rectangle := TRectangle.Create; Rectangle.Draw; // calls TRectangle.Draw Rectangle.Destroy; end;
Virtual and dynamic methodsTo make a method virtual or dynamic, include the virtual or dynamic directive in its declaration. Virtual and dynamic methods, unlike static methods, can be overridden in descendant classes. When an overridden method is called, the actual (runtime) type of the class or object used in the method call--not the declared type of the variable--determines which implementation to activate.To override a method, redeclare it with the override directive. An override declaration must match the ancestor declaration in the order and type of its parameters and in its result type (if any).In the following example, the Draw method declared in TFigure is overridden in two descendant classes.type TFigure = class procedure Draw; virtual; end; TRectangle = class(TFigure) procedure Draw; override; end; TEllipse = class(TFigure) procedure Draw; override; end;Given these declarations, the following code illustrates the effect of calling a virtual method through a variable whose actual type varies at runtime.var Figure: TFigure; begin Figure := TRectangle.Create; Figure.Draw; // calls TRectangle.Draw Figure.Destroy; Figure := TEllipse.Create; Figure.Draw; // calls TEllipse.Draw Figure.Destroy; end;Only virtual and dynamic methods can be overridden. All methods, however, can be overloaded; see Overloading methods.Virtual versus dynamicVirtual and dynamic methods are semantically equivalent. They differ only in the implementation of method-call dispatching at runtime. Virtual methods optimize for speed, while dynamic methods optimize for code size.In general, virtual methods are the most efficient way to implement polymorphic behavior. Dynamic methods are useful when a base class declares many overridable methods which are inherited by many descendant classes in an application, but only occasionally overridden.NoteOnly use dynamic methods if there is a clear, observable benefit. Generally, use virtual methods.
1、静态方法在编译时确定了函数入口地址
静态方法不可override
静态方法是默认方法2、虚拟方法在运行时从virtual method table(VMT)确定函数入口地址
虚拟方法可以被子类override3、动态方法在运行时,从dynamic method table(DMT)确定函数入口地址
动态方法可以被子类override
Static methodsMethods are by default static. When a static method is called, the declared (compile-time) type of the class or object variable used in the method call determines which implementation to activate. In the following example, the Draw methods are static.type
TFigure = class
procedure Draw;
end;
TRectangle = class(TFigure)
procedure Draw;
end;Given these declarations, the following code illustrates the effect of calling a static method. In the second call to Figure.Draw, the Figure variable references an object of class TRectangle, but the call invokes the implementation of
Draw in TFigure, because the declared type of the Figure variable is TFigure.var
Figure: TFigure;
Rectangle: TRectangle;
begin
Figure := TFigure.Create;
Figure.Draw; // calls TFigure.Draw
Figure.Destroy;
Figure := TRectangle.Create;
Figure.Draw; // calls TFigure.Draw
TRectangle(Figure).Draw; // calls TRectangle.Draw
Figure.Destroy;
Rectangle := TRectangle.Create;
Rectangle.Draw; // calls TRectangle.Draw
Rectangle.Destroy;
end;
TFigure = class
procedure Draw; virtual;
end;
TRectangle = class(TFigure)
procedure Draw; override;
end;
TEllipse = class(TFigure)
procedure Draw; override;
end;Given these declarations, the following code illustrates the effect of calling a virtual method through a variable whose actual type varies at runtime.var
Figure: TFigure;
begin
Figure := TRectangle.Create;
Figure.Draw; // calls TRectangle.Draw
Figure.Destroy;
Figure := TEllipse.Create;
Figure.Draw; // calls TEllipse.Draw
Figure.Destroy;
end;Only virtual and dynamic methods can be overridden. All methods, however, can be overloaded; see Overloading methods.Virtual versus dynamicVirtual and dynamic methods are semantically equivalent. They differ only in the implementation of method-call dispatching at runtime. Virtual methods optimize for speed, while dynamic methods optimize for code size.In general, virtual methods are the most efficient way to implement polymorphic behavior. Dynamic methods are useful when a base class declares many overridable methods which are inherited by many descendant classes in an application, but only occasionally overridden.NoteOnly use dynamic methods if there is a clear, observable benefit. Generally, use virtual methods.