インターフェイス
InterfaceDeclaration: interface Identifier BaseInterfaceList InterfaceBody InterfaceTemplateDeclaration BaseInterfaceList: Empty : InterfaceClasses InterfaceBody: { } { InterfaceBodyDeclarations } InterfaceBodyDeclarations: InterfaceBodyDeclaration InterfaceBodyDeclaration InterfaceBodyDeclarations InterfaceBodyDeclaration: { DeclDef }
インターフェイスは、そのインターフェイスを継承する関数が 必ず実装する必要のある関数のリストを記述したものです。 インターフェイスを実装したクラスへの参照は、 そのインターフェイスへの参照へと変換できます。
Win32のCOM/OLE/ActiveXのような、 ある種のOSのシステムオブジェクトは特別なinterfaceを提供しています。Dのインターフェイスで COM/OLE/ActiveX と互換性を持つものは COM Interfaceと呼ばれます。
インターフェイスは、クラスから派生することはできません。 派生元は他のインターフェイスに限られます。クラスは、同じインターフェイスを複数回継承することはできません。
interface D { void foo(); } class A : D, D // エラー、インターフェイスの重複 { }インターフェイスのインスタンスは作成できません。
interface D { void foo(); } ... D d = new D(); // エラー、インターフェイスのインスタンスは作成不可
インターフェイスのメンバ関数は実装を持ちません。
interface D { void bar() { } // エラー、実装はできない }
インターフェイス関数は、 それを継承するクラスで全て定義されている必要があります:
interface D { void foo(); } class A : D { void foo() { } // ok, 実装を提供している。 } class B : D { int foo() { } // エラー, void foo() の実装がない。 }インターフェイスは継承して、関数をオーバーライドできます:
interface D { int foo(); } class A : D { int foo() { return 1; } } class B : A { int foo() { return 2; } } ... B b = new B(); b.foo(); // 2 を返す D d = cast(D) b; // ok, B は AによるDの実装を継承しているので。 d.foo(); // 2 を返す
インターフェイスは、派生クラスで再実装可能です:
interface D { int foo(); } class A : D { int foo() { return 1; } } class B : A, D { int foo() { return 2; } } ... B b = new B(); b.foo(); // 2 を返す D d = cast(D) b; d.foo(); // 2 を返す A a = cast(A) b; D d2 = cast(D) a; d2.foo(); // 2 を返す。BのDではなくAのDに見えるけれど。
インターフェイスを再実装するには、その全ての関数を実装しなければなりません。 基底クラスからの継承はされません:
interface D { int foo(); } class A : D { int foo() { return 1; } } class B : A, D { } // エラー、インターフェイス D のための foo() が無い
COM インターフェイス
インターフェイスの一種として、COMインターフェイスがあります。COMインターフェイスは、 WindowsのCOMオブジェクトとして直接適合するように設計されます。全ての COM オブジェクトは COMインターフェイスによって表現でき、COMインターフェイスを持つ全ての D言語のオブジェクトは、外部のCOMクライアントから使用できます。
COMインターフェイスは、std.c.windows.com.IUnknown から派生することで定義します。COMインターフェイスは、 D言語の通常のインターフェイスと以下の点で異なります:
- std.c.windows.com.IUnknown から派生している。
- DeleteExpression の引数として使えない。
- 参照は、周囲のクラスのオブジェクトへのUpcastや、 派生インターフェイスへのDowncastをすることが許されない。 この目的には、COMの標準的なやり方で適切な QueryInterface() が実装されていなければなりません。
- COMインターフェイスから派生したクラスはCOMクラスです。
- COMクラスのメンバ関数のデフォルトのリンケージは extern(System) です。
- vtbl[] の先頭のメンバは InterfaceInfo へのポインタではなく、最初の仮想関数ポインタになります。