一、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; 二、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 三、override & inherited override是用來重載父類的procedure, 如果父類是virtual 或者 dynamic 方法的,就可以使用inherited,來調用父類中的代碼。 四、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... 五、reintroduce 覆蓋父類中的virtual 方式的內容。(編譯器不會提示“xxx 被hide了”) 六、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; 七、forward declaration提前定義。 用於類被提前使用。注意fd的class后面要立即加“;”不能使用括號和基類。 type TFigure = class; // forward declaration TDrawing = class Figure: TFigure; ... end; TFigure = class // defining declaration Drawing: TDrawing; ... end; 八、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;
參考:http://www.cnblogs.com/key-ok/p/3380401.html
