2013-05-12 130 views
-1

我有一個父類,可能有兩個子類:如何實現繼承

TEmailBaseAccount = class 
    Connected: boolean; 

    setting: TEmailAccountSettings; 
    folders: TEmailAccountFolders; 
    procedure Connect; virtual; abstract; 
    end; 

    TEmailIMAPAccount = class(TEmailBaseAccount) 
    IdIMAP4: TIdIMAP4; 
    OpenSSLHandler: TIdSSLIOHandlerSocketOpenSSL; 

    procedure Connect; override; 
    end; 

    TlEmailPOP3Account = class(TEmailBaseAccount) 
    IdPOP3: TIdIPOP3; 
    OpenSSLHandler: TIdSSLIOHandlerSocketOpenSSL; 

    procedure Connect; override; 
    end; 

我使用的是通用從TList保持電子郵件帳戶的列表:

TEmailAccountList = class(TList<TEmailBaseAccount>) 
    procedure SaveToStream(Stream: TStream); 
    procedure LoadFromStream(Stream: TStream); 
    constructor Create(AOwner: TObject); 
    destructor Destroy; 
    end; 

和使用以下代碼將電子郵件帳戶添加到列表中:

procedure TEmailAccountList.LoadFromStream(Stream: TStream); 
var 
    a, c: Integer; 
    e: TEmailBaseAccount; 
begin 
    c := ReadStreamInt(Stream); 
    for a := 0 to c - 1 do 
    begin 
    e := TEmailBaseAccount.Create(FOwnerEmailEngine); 
    e.LoadFromStream(Stream); 
    Add(e); 
    end; 

end; 

procedure TEmailAccountList.SaveToStream(Stream: TStream); 
var 
    a, c: Integer; 
    e: TEmailBaseAccount; 
begin 
    c := Count; 
    WriteStreamInt(Stream, c); 
    for a := 0 to Count - 1 do 
    Items[a].SaveToStream(Stream); 
end; 

在運行時,我需要區分第e 2類兒童班使用類似:

if account is TEmailIMAPAccount then 
    ... 
else if account is TEmailPOP3Account then 
    ... 

我確信我的原始類聲明和TList聲明不適合此要求。在這種情況下需要做什麼改變?

TIA。

回答

1

您的類型聲明絕對沒問題。你的問題大概是,當你從流中讀取一個項目時,你不知道它是什麼類型。你不能使用is,因爲你還沒有實例。

通過向每個實例的流寫入類型代碼來解決該問題。當您從流中讀取數據時,請閱讀類型代碼並使用它來確定要實例化的類型。

這類持續流是容易得多使用的持久性框架,發出XML,JSON,YAML等

0

而不是序列化的完整的,高度實現特定的對象,我會只寫帳戶屬性(電子郵件帳戶類型,用戶憑據,服務器/端口/安全設置)添加到文件。

這允許在不破壞現有設置文件兼容性的情況下修改實現。

此外,我甚至不會考慮一個if <object> is <class> ... else if <object> is <otherclass> ...解決方案。相反,請定義一個簡單的枚舉類型TAccountType = (atPOP3, atIMAP),然後根據帳戶的帳戶類型屬性在案例結構中進行分支,或使用Strategy pattern

+0

我正在做這個。但在某個地方我遇到麻煩,因爲後來它沒有得到正確的類型。我現在正在努力自己解決這個問題,如果解決方案無法解決問題,我會發布更多信息。謝謝! – 2013-05-12 17:10:02

+0

Q中沒有任何關於每個項目如何持續存在的信息。使用枚舉工作正常,但你必須把它放到文件中。這是關鍵。 – 2013-05-12 17:10:14

+0

事情是我的代碼是如此複雜,它很難只發布一段代碼,並期望任何人都能理解。要看到這個問題,你需要看到整個單元是830行.... – 2013-05-12 17:31:45