更新:interfaceキーワードはDartから削除されました。
インターフェイスは、渡される型がインターフェイスの要件を満たしていることを検証しながら、クラスの実装を切り替えることができるので便利です。
次の(よく使用される)例を見てください。
interface Quackable {
void quack();
}
これは、次のようなメソッドに渡されるクラスの要件を定義します。
sayQuack(Quackable quackable) {
quackable.quack();
}
これにより、次のようなQuackableオブジェクトの実装を利用できます。
class MockDuck implements Quackable {
void quack() => print("quack");
}
class EnterpriseDuck implements Quackable {
void quack() {
// connect to three enterprise "ponds"
// and eat some server bread
// and say "quack" using an messaging system
}
}
これらの実装は両方ともsayQuack()関数で機能しますが、一方が他方よりも大幅に少ないインフラストラクチャを必要とします。
sayQuack(new EnterpriseDuck());
sayQuack(new MockDuck());
私は、Javaの世界では、「エンタープライズアヒル」を利用するソリューションを構築するときに、このパターンを常に使用しています。ローカルで開発する場合、必要なのは、sayQuack()関数を呼び出して、ハードコードされたモックデータを返すことだけです。
ダックタイピング
Dartはオプションで入力されるため、実際にインターフェイスを使用する必要はありません。正しいメソッドシグネチャを含むクラスを作成するだけで機能します(ただし、ツールはそれを検証できません)。
class Person { // note: no implements keyword
void quack() => "I'm not a duck";
}
sayQuack(new Person()); // provides the quack method, so this will still work
すべてのクラスはインターフェースです
最後に、すべてのクラスもインターフェースです。これは、サードパーティのシステムがインターフェイスを使用せずに作成された場合でも、それがインターフェイスであるかのように具象クラスを使用できることを意味します。
たとえば、次のエンタープライズライブラリを想像してみてください。
class EnterpriseDuck { // note: no implements keyword
void quack() {
// snip
}
}
sayQuack(EnterpriseDuck duck) { // takes an instance of the EnterpriseDuck class
duck.quack();
}
そして、タイプチェッカーが検証できる方法で、モックダックをsayQuackメソッドに渡します。EnterpriseDuckをインターフェイスとして使用するだけで、mockDuckを作成して、EnterpriseDuckによって暗黙的に示されるインターフェイスを実装できます。
class MockDuck implements EnterpriseDuck {
void quack() => "I'm a mock enterprise duck";
}
多重継承
多重継承に関しては、これはDartでは不可能です。ただし、複数のインターフェースを実装し、必要なメソッドの独自の実装を提供することはできます。例:
class MultiDuck implements Quackable, EnterpriseDuck, Swimable {
// snip...
}
インターフェイスはデフォルトのクラスを持つことができます
Dartを使用すると、ほとんどの「クラス」が実際にはインターフェイスであることがわかります。リスト、文字列などはすべて、デフォルトの実装が提供されているインターフェイスです。電話するとき
List myList = new List();
実際にはリストインターフェイスを使用しており、新しいキーワードはインターフェイスから基になるデフォルトのリスト実装にリダイレクトします。
チームでの開発に関して
インターフェイスは、オープンソースの世界でもチーム開発に役立ちます。インターフェイスは、コンポーネントが私のコンポーネントと連動するように構築する必要のあるメソッドとプロパティを定義します。そのインターフェイスの独自のテスト実装を構築できます。また、そのインターフェイスの具体的な実装を構築できます。両方が完了したら、統合できます。公開された共有インターフェースがなければ、実際に始める前に具体的な実装を提供する必要があります。
お役に立てば幸いです。