2013-05-12 132 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