階層全体にわたるインターフェイスの使用
インターフェイスの使用 への移動
インターフェイスを使用することにより、クラスの使用方法と実装方法を切り離すことができます。同じ基底クラスの下位クラスでなくても、同じインターフェイスを実装できます。どちらかのクラスからインターフェイスを取得することにより、クラスの型がわからなくても同じメソッドを呼び出すことができます。直接関係のないオブジェクトどうしでも、同じインターフェイスを実装しているので、それらのオブジェクトに対して、同じメソッドをこのように多態的に使用することができます。たとえば、次のようなインターフェイスがあるとしましょう。
IPaint = interface procedure Paint; end;
また、次のようにクラスが 2 つあるとします。
TSquare = class(TPolygonObject, IPaint) procedure Paint; end; TCircle = class(TCustomShape, IPaint) procedure Paint; end;
2 つのクラスが共通の上位クラスを共有しているかどうかにかかわらず、次のように、IPaint 型の変数に関して代入互換性があります。
var Painter: IPaint; begin Painter := TSquare.Create; Painter.Paint; Painter := TCircle.Create; Painter.Paint; end;
このことは、TCircle と TSquare を共通の上位クラス(たとえば TFigure など)の下位クラスとすることでも実現可能です(TFigure では仮想メソッド Paint を宣言しています)。その場合は、TCircle と TSquare の両方で Paint メソッドをオーバーライドすることになります。そして、上記の例の IPaint を TFigure に置き換えます。一方、次のインターフェイスを考えてみましょう。
IRotate = interface procedure Rotate(Degrees: Integer); end;
IRotate は、四角形には意味がありますが、円には意味がありません。クラスの方は次のようになるでしょう。
TSquare = class(TRectangularObject, IPaint, IRotate) procedure Paint; procedure Rotate(Degrees: Integer); end; TCircle = class(TCustomShape, IPaint) procedure Paint; end;
後で、IRotate インターフェイスを実装するクラス TFilledCircle を作成すれば、円に回転機能を付け加えなくても、円を塗りつぶすパターンを回転させることができるようになるでしょう。
メモ: これらの例では、直接の基底クラスまたは上位クラスが IInterface(すべてのインターフェイスの派生元となる基底インターフェイス)のメソッドを既に実装していることを前提としています。IInterface の詳細については、「IInterface の実装」や「インターフェイス オブジェクトのメモリ管理」を参照してください。