Classes and objects
begin
Figure := TFigure.Create;
Figure.Draw;// 调用TFigure.Draw
Figure.Destroy;
Figure := TRectangle.Create;
Figure.Draw;// 调用TFigure.Draw
TRectangle(Figure).Draw; // 调用TRectangle.Draw
Figure.Destroy;
Rectangle := TRectangle.Create;
Rectangle.Draw; // 调用TRectangle.Draw
Rectangle.Destroy;
end;
Virtual and dynamic methods(虚方法和动态方法)
要实现虚方法或动态方法,在声明时包含virtual或dynamic指示字。不像静态方法,虚方法和动态方法能在派生类中被覆盖。当调用一个被覆盖的方法时,类或对象的实际类型决定了哪种实现被调用(运行时),而不是它们被声明的类型。
要覆盖一个方法,使用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;
只有虚方法和动态方法能被覆盖,但是,所有方法都能被重载,请参考
Overloading methods
- 103 - 。
Classes and objects
Virtual versus dynamic(比较虚方法和动态方法)
虚方法和动态方法在语义上是相同的,唯一的不同是在运行时决定方法调用的实现方式上,虚方法在速度上进行了优化,而动态方法在代码大小上做了优化。
通常情况下,虚方法是实现多态行为的最有效的实现方式。当基类声明了大量的要被许多派生类继承的(可覆盖的)方法、但只是偶尔才覆盖时,动态方法还是比较有用的。
Overriding versus hiding(比较覆盖和隐藏)
在声明方法时,如果它和继承的方法具有相同的名称和参数,但不包含override,则新方法仅仅是隐藏了继承下来的方法,并没有覆盖它。这样,两个方法在派生类中都存在,方法名是静态绑定的。比如,type
T1 = class(TObject)
procedure Act; virtual;
end;
T2 = class(T1)
procedure Act; // 重新声明Act,但没有覆盖
end;
var
SomeObject: T1;
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-23665-75.html
凡是敌人反对的我们就支持
说得很对
身材好