Delphi接口和类变量类型

时间:2017-05-30 09:14:24

标签: delphi

我已经读过,接口对于解码代码是一件好事,而Nick Hodges已经写了很好的章节。读到我已经生成了这段代码:

//interfaces
type
 ILocalization = interface
  ['{1D144BCE-7D79-4672-8FB5-235422F712EE}']
  function localize(const aWordId: string): string;
 end;

type
 IActions = interface
  ['{31E8B24F-0B17-41BC-A9E4-F93A8E7F6ECF}']
  procedure addWord(const aIndex, aWord: string);
  procedure removeWord(const aIndex: string);
 end;

//implementation
type
 TLocalization = class sealed (TInterfacedObject, ILocalization, IActions)
  private
   FTranslationList: TDictionary<string, string>;
  public
   constructor Create;
   destructor Destroy; override;
   //interface implementations
   function localize(const aWordId: string): string;
   procedure addWord(const aIndex, aWord: string);
   procedure removeWord(const aIndex: string);
 end;

我打算用这个类本地化(翻译)我的delphi android应用程序。

当我要创建该类的实例时,我会执行以下操作。

var
 Italiano: TLocalization;
begin
 Italiano := TLocalization.Create;
end;

由于TLocalization应该继承AddRef而Release I最终不会尝试这个,但即使Italiano是类类型而不是接口类型,这是否会发生?

我的意思是:

  • Italiano:TLocalization - &gt;在这里我可以使用所有方法
  • Italiano:ILocalization - &gt;这里我只能使用localize函数

鉴于(正如我已经说过的)TLocalization继承了AddRef和Release I,如果我理解正确,则不必释放。它应该与ILocalization相同,但它有其他好处吗?我不明白上面两种情况的区别是什么

1 个答案:

答案 0 :(得分:5)

var
  Italiano: TLocalization;
begin
  Italiano := TLocalization.Create;
  // do stuff
end;

这可以让您了解混合不同生命周期模型的陷阱。如代码所示,AddRef尚未被调用,因此引用计数为0.因此,您将泄漏此对象。

因此您可以将代码更改为:

var
  Italiano: TLocalization;
begin
  Italiano := TLocalization.Create;
  try
    // do stuff
  finally
    Italiano.Free;
  end;
end;

现在你不会泄漏。

大。但是如果你确实参考了会发生什么呢?

var
  Italiano: TLocalization;
  Localization: ILocalization;
begin
  Italiano := TLocalization.Create;
  try
    Localization := Italiano as ILocalization;
    // do stuff
  finally
    Italiano.Free;
  end;
end;

当您分配到AddRef时,系统会调用Localization。因此引用计数变为1.当Localization超出范围时,将调用Release并且引用计数返回0并且实例被销毁。不幸的是,你也在明确地摧毁它。对象需要被摧毁一次。

要遵循的最简洁和最简单的规则不是混合终身模型。如果您通过引用计数进行终身管理,请仅执行此操作。确保在创建对象时始终引用该对象,并让编译器生成引用计数代码以管理该生命周期。

确保遵循该规则的一种方法是确保您只能通过接口引用访问该对象。像这样:

var
  Italiano: ILocalization;
begin
  Italiano := TLocalization.Create;
  // do stuff
end;