2012-12-05 34 views
6

我有我的很多子類我重載一個重要的抽象過程的父類,如下所示的示例代碼:如何重載父類中引入的虛函數?

TCParent = Class 
private 
public 
procedure SaveConfig; virtual; abstract; 

end; 

TCChild = Class(TCParent) 
private 
public 
procedure SaveConfig; override; 
end; 

現在有我需要(超載)與另一saveconfig的過程,將這個程序接受參數,但我不想在父類中做出重大更改,這可能需要我去更改所有其他子類。

有沒有一種方法可以在這個特定的子類中重載SaveConfig而不對父類和從它繼承的其他子類做大的修改?

+3

爲什麼這個新的'SaveConfig'必須具有相同的名稱?爲什麼不把它稱爲別的東西呢? – awmross

+1

@awmross因爲當我想添加一個重載'TStream.Seek',需要一個'Int64'偏移量。不要把這個問題和這個例子混爲一談。 –

回答

9

您可以使用reintroduce添加新的重載方法。請注意,子級中的reintroduce; overload;的順序是必需的;如果你反轉它們,代碼將不能編譯。

TCParent = Class 
private 
public 
procedure SaveConfig; virtual; abstract; 
end; 

TCChild = Class(TCParent) 
private 
public 
procedure SaveConfig; overload; override; 
procedure SaveConfig(const FileName: string); reintroduce; overload; 
end; 

(測試在Delphi 7,所以應該在它和所有更高版本。)

+0

不幸的是我使用的是Delphi 7 :(所以當我試圖編譯上面的代碼時,我得到了錯誤: [錯誤] uClassChild.pas(13):聲明'SaveConfig'與前面的聲明不同 指向行 程序SaveConfig(const FileName:string); reintroduce; override; – MChan

+0

然後你就沒有運氣了AFAIK,在D7中沒有辦法做同樣的事情(這就是爲什麼他們引入了新指令'reintroduce' ) –

+1

但是在Delphi 7中確實存在,它只是沒有使用上面的proc定義編譯...更具體地說,D7不接受在這個特定定義中重新引入,但它通常會在其他定義中接受它 – MChan

4

既然你不想更改其他的後代,我建議增加一個可選字段父類來保存參數,那麼任何希望使用參數的後代都可以使用它們。這樣,您不必更改覆蓋的SaveConfig()的簽名。例如:

type 
    TCParent = class 
    protected 
    SaveConfigParams: TStrings; // or whatever... 
    public 
    procedure SaveConfig; overload; virtual; abstract; 
    procedure SaveConfig(Params: TStrings); overload; 
    end; 

procedure TCParent.SaveConfig(Params: TStrings); 
begin 
    SaveConfigParams := Params; 
    try 
    SaveConfig; 
    finally 
    SaveConfigParams := nil; 
    end; 
end; 

type 
    TCChild = class(TCParent) 
    public 
    procedure SaveConfig; override; 
    end; 

procedure TCChild.SaveConfig; 
begin 
    if SaveConfigParams <> nil then 
    begin 
    // do something that uses the parameters... 
    end else begin 
    // do something else... 
    end; 
end; 

type 
    TCChild2 = class(TCParent) 
    public 
    procedure SaveConfig; override; 
    end; 

procedure TCChild2.SaveConfig; 
begin 
    // do something, ignoring the SaveConfigParams... 
end; 
+0

感謝您的幫助,但我不確定我是否明白這一部分....所以只是爲了確保我正確地理解了您的意思......您的意思是在兒童班取決於SaveConfigParams在IF語句中我將在IF語句下執行代碼....如果這是正確的,那麼父類中的參數化SaveConfig過程的需求是什麼? – MChan

+1

如果需要,子類可以選擇檢查是否指定了參數,如果檢測到,則相應地調整其行爲,否則只需忽略它們並執行其他操作。這就是整個觀點 - 參數是可選的,但存儲在每個孩子可以看到的父母身上,如果需要的話。這就是您最初所要求的 - 支持參數,而無需在任何地方進行更改。最終,更好的選擇是咬住子彈並改變'SaveConfig()'給它可選的輸入參數,然後在每個孩子中進行更改。你的代碼會更乾淨。 –