nakamurakko’s blog

仕事で覚えたこと、勉強したことを自分のメモ代わりに書いていこうかなと。

Delphiで手抜きインターフェース取り込み

Delphiにもインターフェースは存在する。
全てのインターフェースの基本クラスは「IInterface」。

ただし、Javaや.NETとは違い、インターフェースを継承すると
・_AddRefと_Release(参照カウントメソッド)
・QueryInterface(指定したインターフェイスへの参照を返す)
も実装する必要があるので、

  1. THoge = class(TObject, IInterface)


とだけ書くとコンパイルエラーになる。(「IInterface.QueryInterface の実装が見つかりません」などのエラーが3つ出る。)

そこで、「既に実装が終わっているクラスを取り込む」という手抜き実装を行う。
Delphiのクラス階層で最初に出てくるでインターフェースの実装が最初に行われているのは「TComponent」。

つまり、

  1. THoge = class(TComponent, IInterface)


と書くとコンパイルエラーが無くなる。

例えば、インターフェースを

  1. IInformation = interface
  2.   procedure GetInfo;
  3. end;


と用意し、そのインターフェースを使用するクラスを、TComponentを継承して実装する。

  1. TInformation = class(TComponent, IInformation)
  2.   procedure GetInfo; // これは実装する。
  3. end;


とすれば、AddRef、_Release、QueryInterfaceはTComponentで実装済みなので、自分で書く必要が無くなる。

TComponent以下であればTButtonなどでも出来るけど、TComponentを継承していないクラスやTComponentの親クラス(TPersistent、TObject)を継承する場合は_AddRef、_Release、QueryInterfaceを自分で実装するしか無さそう。TObjectから派生したTInterfacedObjectを使えば良い、という事をpikさんから教えてもらいました。ありがとうございました。

TInterfacedObjectの定義を見ると、

  1. TInterfacedObject = class(TObject, IInterface)


となっているため、今回の用件を満たしている。
なので、

  1. TInformation = class(TInterfacedObject, IInformation)


もAddRedなどを自分で書く事無く使用可能。