2012-05-08 10 views
8

私はダーツのドキュメントを読んでいましたが、ちょっと混乱していました。おそらく、私はRubyからインターフェイスを使用する方法について説明しています。もちろん、インターフェイスはDartに固有のものではなく、インターフェイスを使用する必要があるときにはかなり多くの説明があります。たとえば、This oneは、インターフェイスはあなたがチームにいるときにのみ有用であると言っているようです。誰もが誰かのコードを読んで再利用するオープンソースの世界では、それはどういう意味ですか?Dartでインターフェイスを使用するタイミングは?

一つの興味深い説明私はインタフェースが使用されていることを暗示しているように見えた見てきました:彼らは何らかの形での不在のための回避策として機能し、そのことについては

多重継承が不足している言語で
  1. 、および
  2. 多重継承。

私はそれを理解できません。 Rubyのモジュールは実際のメソッドを実際のボディで定義できるため、回避策です。インタフェースは、それを実装するクラスが持つ必要があるメソッドを定義することしかできません。キャッチは何ですか?私はすぐにインターフェイスを使用しての価値を見ることができる実際の有用な例を教えてもらえますか?

P.S.関連するノートでは、Dartで複数の継承を使用する方法はありますか?

答えて

19

インターフェイスは、インターフェイスの要件を満たしていることの検証を許可しながら、クラスの実装を切り替えることができるので便利です。にあなたを可能に

sayQuack(Quackable quackable) { 
    quackable.quack(); 
} 

interface Quackable { 
    void 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()関数で動作しますが、一方のインフラストラクチャには他のインフラストラクチャよりも大幅に少ないインフラストラクチャが必要です。いくつかの「企業鴨」を活用したソリューションを構築するとき、私は、Javaの世界では、このパターンのすべての時間を使用し

sayQuack(new EnterpriseDuck()); 
sayQuack(new MockDuck()); 

。ローカルで開発するときは、単にsayQuack()関数を呼び出してハードコードされた模擬データを返すだけでよいだけです。ダートは、任意に入力されているので

を入力ダック

ツールはできませんが、あなたが実際に(単に正しいメソッドのシグネチャがうまくいく含むクラスを書いて、インタフェースを使用する必要はありませんそれを検証する)。

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を使用することにより、EnterpriseDuckによって暗黙のインタフェースを実装するために、あなたのmockDuckを作成することができます。

class MockDuck implements EnterpriseDuck { 
    void quack() => "I'm a mock enterprise duck"; 
} 

多重継承

多重継承の面では、これはダートでは不可能です。あなたは、しかし、複数のインターフェースを実装し、必要なメソッドの独自の実装を提供することができ、例えば:あなたはダーツを使用すると、あなたは、ほとんどの「クラスが見つかります

class MultiDuck implements Quackable, EnterpriseDuck, Swimable { 
    // snip... 
} 

のインターフェイスは、デフォルトのクラスを持つことができます"は実際にインターフェイスです。リスト、文字列などはすべて、デフォルトの実装が提供されているインターフェイスです。あなたが電話をするとき

List myList = new List(); 

実際にはListインターフェイスを使用しています。新しいキーワードは、インターフェイスから基になるデフォルトのList実装にリダイレクトされます。チームに

インタフェースを開発に関して

も、オープンソースの世界では、チーム開発に有用です。インターフェイスは、コンポーネントが自分のコンポーネントで動作するように構築する必要があるメソッドとプロパティを定義します。そのインタフェースの独自のテスト実装を構築することができ、私はそのインタフェースの具体的な実装を構築することができます。両方が完了したら、統合することができます。公開された共有インターフェースがなければ、私が具体的な実装を提供してから、本当に始めることができます。

希望に役立ちます!

+2

本当にありがとう、クリス、それはまさに私が必要としていたものです。また、例のクラス名は愛らしいです。 – snitko

+0

はあなたのコードの2つのコメントは、「// note:no implements keyword」ではなく「// note:no interface keyword」と考えています。 – GameAlchemist

+3

これを更新するか、インターフェイスキーワードがDartで使用されなくなったことを説明するこの記事にコメントを追加することを検討してください。 –

1

インターフェイスはDartの型システムの一部であり、型宣言はオプションです。これは、インタフェースもオプションであることを意味します。

インターフェイスは、オブジェクトが応答するメソッドを文書化するのに役立ちます。インターフェイスを実装する場合は、インターフェイス内のすべてのメソッドを実装することを約束します。

ダーツでは、この情報を使用して、コンパイル時にタイプの不一致の警告を表示し、コードアシストの助けとなる助言を提供し、いくつかのリファクタリングを支援します。

+0

確かに、私はそれらがオプションであることを理解しています。そして私はそれらを使用することでその価値を見ません。コンパイル時の警告は大きな勝利ではないようです。しかし、私は私の評価において根本的に間違っているかもしれないと認めます。だからこそ私は、インターフェイスを使用する価値を実証した実例を探していました。 – snitko

4

基本的に、インターフェイスは複数の継承とは関係ありません。多重継承と濫用インタフェースを偽装することは可能ですが、真の多重継承(またはミックスインや特性)が必要な場合、Dartはそれらを提供しません(現在 - ミックスインはある日)。

明示的な契約とは何ですか?互いに作業する必要がある2つのコンポーネントABがあるとします。 BAから直接呼び出すことはできますが、それはうまくいきますが、次回にBを変更する場合は、その使用方法をAで調べる必要があります。 Bは、明示的なインタフェースを公開していないためです。はい、インタフェースの正しい言葉はではなく、ですが、です。あなたがインターフェイスの背後にBの実装を隠すだけAにそのインターフェースを提供する場合

、あなたは意志でBを変更することができますし、たったの約まだ同じインタフェースをさらす心配します。インターフェイスは複数のクラスによって公開されることもあり、呼び出し元は気にする必要はありません(または知っている)。単語インターフェースがここに二つの意味がある

注:また、ドキュメントに平易な英語で説明することができ、一般的な契約コンポーネントの、そしてあなたが記述できます特殊な言語を構築する(とまた、プログラミング言語の中で契約のいくつかの部分を実行することもできます。

必ずしも言語構成を使用する必要はありませんが、プログラミング言語で許可されているコントラクトの部分を記述するのに適しています。

ここで契約は何ですか?簡単に言えば、コントラクトはの説明であり、コンポーネントがユーザから期待するものと、ユーザがコンポーネントから期待できるものはです。

たとえば、のは、私は数の絶対値を計算する方法を持っているとしましょう:

class MathUtils { 
    /// Computes absolute value of given [number], which must be a [num]. 
    /// Return value is also a [num], which is never negative. 
    absoluteValue(number) { 
    ... here's the implementation ... 
    } 
} 

ここに契約が完全にドキュメンテーションコメントに記述されている(まあ、完全に、我々はまた、記述することができません絶対値は何ですか、これは十分です)。まあ...コメントのいくつかの部分は、言語で直接表現することができます。

class MathUtils { 
    /// Computes absolute value of given [number]. 
    /// Return value is never negative. 
    num absoluteValue(num number) { 
    ... here's the implementation ... 
    } 
} 

単に契約の一部がは、プログラミング言語で表現することができないことに注意してください - ここでは、言語は絶対値このコメントに滞在する必要があり、何であるかわかりません。また、戻り値が負でないことを表現することはできません。したがって、これもコメントにとどまっている必要があります。しかし、実際には、あなたのコードの読者は、絶対値が何であるかを知っている(そして、それは負になることはありませんという)とのコメントが完全に残されることができるようにメソッド名は、目的についてかなり明確である:

class MathUtils { 
    num absoluteValue(num number) { 
    ... here's the implementation ... 
    } 
} 

これで、契約のいくつかの部分が言語手段を使って明示的に表現され、一部は暗黙的に表現されます(あなたは絶対値が分かっている人に頼ります)。

そして、インタフェースはとなり、実装は契約と切り離されています。小規模なプログラムで使用するのはおそらく過剰ですが、大きなプログラム(チームワークを必要としない)を行うときにはお金がかかります。

Uff、これは予想より長くなっていました。希望が役立ちます。

関連する問題