1、override 重載
type
TFigure = class
procedure Draw; virtual;//(個人理解是)父類中可使用父類的,子類中使用子類的。與「四」是有區別的。
end;
TRectangle = class(TFigure)
procedure Draw; override;//a1
end;
TEllipse = class(TFigure)
procedure Draw; override;//a2
end;
使用
var
Figure: TFigure;
begin
Figure := TRectangle.Create;
Figure.Draw; // 執行a1
Figure.Destroy;
Figure := TEllipse.Create;
Figure.Draw; // 執行a2
end;
2、overload 多態
procedure foo(i: integer); overload;
procedure foo(d: double); overload;
procedure foo(v: variant); overload;
典型用法。若是是對於繼承的。必須使用reintroduce
type
T1 = class(TObject)
procedure Test(I: Integer); overload; virtual;
end;
T2 = class(T1)
procedure Test(S: string); reintroduce; overload;
end;
...
SomeObject := T2.Create;
SomeObject.Test('Hello!'); // T2.Test
SomeObject.Test(7); // T1.Test
3、override & inherited
override是用來重載父類的procedure,
若是父類是virtual 或者 dynamic 方法的,就可使用inherited,來調用父類中的代碼。
4、abstract
procedure DoSomething; virtual; abstract;//若是是這個樣式的,表示要在子類中實現(代碼)。而父類中,其餘procedure function可使用這個procedure。
(這裏的virtual彷佛不能被dynamic替換)。
使用procedure DoSomething; virtual; abstract;和procedure DoSomething; virtual;的區別就是,前者的實現代碼在子類,然後者實現代碼在自身。後者能夠在子類中override一下,使其子類也有本身的實現代碼。
2009-4-11
在最近的代碼中發現(不知道是否是D7的緣故)
procedure DoSomething; virtual; abstract;
procedure DoSomething; dynamic; abstract;
都是能夠的。
並且在繼承類中也能夠不寫實現代碼。
在基類中若是要判斷有沒有被繼承類寫實現代碼的方式不是
if Assigned(DoSomething) then ...
而是
if MethodAddress('DoSomething')<>nil then...
5、reintroduce
覆蓋父類中的virtual 方式的內容。(編譯器不會提示「xxx 被hide了」)
6、static
默認就是這個。
咱們常打 procedure test(xx:Integer);其實就是static的。
這個比較好理解。
若是子類中,聲明瞭一個test,跟父類無關。各自用各自的。
除非使用強制轉換。好比:
type
TFigure = class
procedure Draw;
end;
TRectangle = class(TFigure)
procedure Draw;
end;
//實現
var
Figure: TFigure;
Rectangle: TRectangle;
begin
Figure := TFigure.Create;
Figure.Draw; // 父類用父類的 TFigure.Draw
Figure.Destroy;
Figure := TRectangle.Create;
Figure.Draw; // 雖然初始化爲子類,可是因爲申明的是父類,因此Figure仍是調用了父類的Draw TFigure.Draw
TRectangle(Figure).Draw; // 強制轉換成子類,就能夠用TRectangle.Draw
Figure.Destroy;
Rectangle := TRectangle.Create;
Rectangle.Draw; // 子類用子類的 TRectangle.Draw
Rectangle.Destroy;
end;
7、forward declaration提早定義。
用於類被提早使用。注意fd的class後面要當即加「;」不能使用括號和基類。
type
TFigure = class; // forward declaration
TDrawing = class
Figure: TFigure;
...
end;
TFigure = class // defining declaration
Drawing: TDrawing;
...
end;
8、virtual 和 dynamic
虛擬方法佔用的內存大,調用速度快;動態方法相反。
現在,哪有PC內存不夠的。
因此,筆者建議,就使用virtual吧。
2009-04-07
我知道了,內存是有不夠用的時候。
因此這裏修改說法,須要來回調用的用virtual,通常只用到1,2次的用dynamic。
像筆者通常寫一個基類函數,只用一次,因此大部分都改爲dynamic了。
可是有個地方必需要用virtual
private
FItem:Integer
procedure SetItem(Value:Integer);virtual;//dynamic不容許
public
property Item:Integer;read FItem write SetItem;
end;ide