206

私は開発学習の段階で、インターフェースについてもっと学ばなければならないと感じています。

私はそれらについてよく読んでいますが、理解できないようです。

「Walk」、「Run」、「GetLegs」などの IAnimal インターフェイスを備えた Animal 基本クラスのような例を読んだことがありますが、何かに取り組んだことがなく、「インターフェイスを使用する必要がある」と感じました。ここ!"

私は何が欠けていますか?なぜ私が理解するのが難しい概念なのでしょうか。私は、具体的な必要性に気付かないかもしれないという事実に怯えています-主にそれらを理解するためのいくつかの側面が欠けているためです! 開発者であるという点で、何かが欠けているように感じます! 誰かがこのような経験をして突破口を開いた場合、この概念を理解する方法についてのヒントをいただければ幸いです. ありがとうございました。

4

24 に答える 24

158

この具体的な問題を解決します:

4 つの異なるタイプの a、b、c、d があります。コード全体に次のようなものがあります。

a.Process();
b.Process();
c.Process();
d.Process();

なぜ彼らに IProcessable を実装させないのか

List<IProcessable> list;

foreach(IProcessable p in list)
    p.Process();

たとえば、すべて同じことを行う 50 種類のクラスを追加すると、これははるかにうまくスケーリングされます。


別の具体的な問題:

System.Linq.Enumerable を見たことがありますか? IEnumerable を実装する任意の型で動作する多数の拡張メソッドを定義します。IEnumerable を実装するものは基本的に「順序付けされていない foreach 型パターンでの反復をサポートする」と述べているため、任意の列挙可能な型に対して複雑な動作 (Count、Max、Where、Select など) を定義できます。

于 2009-01-14T19:06:32.050 に答える
140

ジミーの答えはとても好きですが、何かを追加する必要があると感じています。全体の鍵は、IProcessableの「able」です。これは、インターフェイスを実装するオブジェクトの機能(またはプロパティですが、C#プロパティの意味ではなく「本質的な品質」を意味します)を示します。IAnimalはおそらくインターフェースの良い例ではありませんが、システムに歩くことができるものがたくさんある場合は、IWalkableが良いインターフェースになる可能性があります。犬、牛、魚、ヘビなどの動物から派生したクラスがある場合があります。最初の2つはおそらくIWalkableを実装し、後の2つは歩かないので歩きません。ここで、「犬と牛が派生する別のスーパークラス、WalkingAnimalを持っていないのはなぜですか?」と尋ねます。答えは、ロボットなど、継承ツリーの完全に外側にあり、歩くこともできるものがある場合です。RobotはIWalkableを実装しますが、おそらくAnimalから派生することはありません。歩くことができるもののリストが必要な場合は、

ここで、IWalkableをIPersistableのようなよりソフトウェアに置き換えます。これにより、実際のプログラムで見られるものに非常に近くなります。

于 2009-01-14T19:13:45.637 に答える
75

同じ機能の実装が異なる場合は、インターフェイスを使用します。

共通の具体的な実装を共有する必要がある場合は、抽象/基本クラスを使用します。

于 2009-01-14T19:10:25.350 に答える
34

コントラクトのようなインターフェースを考えてみてください。「これらのクラスは、これらの一連のルールに従う必要があります」と言う方法です。

したがって、IAnimal の例では、「IAnimal を実装するクラスで Run、Walk などを呼び出せなければならない」という言い方になります。

なぜこれが役立つのですか?たとえば、オブジェクトで Run と Walk を呼び出すことができなければならないという事実に依存する関数を作成したい場合があります。次のようにすることができます。

public void RunThenWalk(Monkey m) {
    m.Run();
    m.Walk();
}

public void RunThenWalk(Dog d) {
    d.Run();
    d.Walk();
}

...そして、走ったり歩いたりできることがわかっているすべてのオブジェクトに対してそれを繰り返します。ただし、IAnimal インターフェイスを使用すると、次のように関数を 1 回定義できます。

public void RunThenWalk(IAnimal a) {
    a.Run();
    a.Walk();
}

インターフェイスに対してプログラミングすることにより、クラスがインターフェイスの意図を実装することを基本的に信頼しています。したがって、私たちの例では、「彼らが走って歩いている限り、彼らがどのように走って歩いているかは気にしません。私のRunThenWalkは、彼らがその合意を満たしている限り有効です。それは、他に何も知らなくても完全にうまく機能します。クラス。"

この関連する質問にも良い議論があります。

于 2009-01-14T19:05:12.987 に答える
21

あまり心配しないでください。多くの開発者は、インターフェースを書く必要はめったにありません。.NETフレームワーク内で使用可能なインターフェイスを頻繁に使用しますが、すぐに作成する必要がないと感じたとしても、それは驚くべきことではありません。

私がいつも誰かに与える例は、Sailboat クラスと Viper クラスを持っている場合です。それぞれ Boat クラスと Car クラスを継承しています。ここで、これらすべてのオブジェクトをループして、それらのメソッドを呼び出す必要があるとしますDrive()。次のようなコードを書くこともできますが、

if(myObject is Boat)
    ((Boat)myObject).Drive()
else
    if (myObject is Car)
        ((Car)myObject).Drive()

次のように書くと、はるかに簡単になります。

((IDrivable)myObject).Drive()
于 2009-01-14T19:11:02.790 に答える
18

私は軍隊のアナロジーが好きです。

軍曹は、あなたがソフトウェア開発者ミュージシャン、または弁護士であるかどうかは気にしません。あなたは兵士
として扱われます。

うーん

軍曹にとっては、一緒に働いている人の特定の詳細を気にせず、すべての
人を兵士の抽象化として扱います (...そして、彼らが兵士のように振る舞わなかった場合は罰します) 。

人が兵士のように振る舞う能力は、ポリモーフィズムと呼ばれます。

インターフェイスは、ポリモーフィズムを実現するのに役立つソフトウェア構造です。

シンプルさを実現するために詳細を抽象化する必要があるのは、あなたの質問に対する答えです。

語源的に「多くのフォーム」を意味するポリモーフィズムは、基本クラスのオブジェクトであるかのように、基本クラスの任意のサブクラスのオブジェクトを処理する機能です。したがって、基本クラスには多くの形式があります。基本クラス自体とそのサブクラスです。

(..) これにより、コードが書きやすくなり、他の人が理解しやすくなります。また、他のサブクラスを後で型のファミリに追加でき、それらの新しいサブクラスのオブジェクトも既存のコードで動作するため、コードを拡張可能にします。

于 2011-04-07T11:36:54.740 に答える
16

単一の変数を複数の型に使用できるようにしたいが、それらの型のすべてがインターフェイス宣言を介して同じメソッドを実装する場合、ジミーはそれを正しく理解しています。次に、インターフェイスの型付き変数で main メソッドを呼び出すことができます。

ただし、インターフェイスを使用するもう 1 つの理由があります。プロジェクト アーキテクトが実装コーダーとは別の人物である場合、または複数の実装コーダーと 1 人のプロジェクト マネージャーがいる場合。担当者は、多数のインターフェースを作成し、システムが相互運用することを確認してから、実装クラスでインターフェースを埋めることを開発者に任せることができます。これは、複数の人が互換性のあるクラスを作成し、並行して作成できるようにするための最良の方法です。

于 2009-01-14T19:10:33.663 に答える
14

私の経験では、インターフェースを作成する原動力は、モッキング フレームワークで単体テストを開始するまで発生しませんでした。インターフェイスを使用するとモックがはるかに簡単になることが十分に明らかになりました (フレームワークはメソッドが仮想であることに依存していたため)。始めると、実装からクラスへのインターフェースを抽象化することの価値がわかりました。実際のインターフェースを作成しない場合でも、メソッドを仮想化するようにしています (オーバーライド可能な暗黙のインターフェースを提供します)。

インターフェイスへのリファクタリングの優れたプラクティスを強化する理由は他にもたくさんありますが、単体テスト/モック化は、実際の経験の最初の「ああ瞬間」を提供したものでした.

編集: 明確にするために、単体テストとモックでは、常に 2 つの実装があります。実際の具体的な実装と、テストで使用される代替のモック実装です。2 つの実装があると、インターフェイスの価値が明らかになります。いつでも実装を置き換えることができるように、インターフェイスの観点から扱います。この場合、モック インターフェイスに置き換えます。クラスが適切に構築されていれば、実際のインターフェースなしでこれを実行できることはわかっていますが、実際のインターフェースを使用すると、これが強化され、よりクリーンになります (読者にとってより明確になります)。私のクラスのほとんどは単一の具体的な実装しか持っていないため、この刺激がなければ、インターフェイスの価値を高く評価していなかったと思います。

于 2009-01-14T19:09:52.510 に答える
10

プログラミングでインターフェースを適切に使用するのに役立つ、プログラミング以外の例をいくつか示します。

電気機器と電気ネットワークの間にはインターフェースがあります。これは、プラグとソケットの形状、およびそれらにかかる電圧/電流に関する一連の規則です。新しい電気デバイスを実装する場合、プラグがルールに従っている限り、ネットワークからサービスを取得できます。これにより、拡張性が非常に簡単になり、調整のコストが削減または削減されます。新しいデバイスがどのように機能するかについて電力会社に通知し、新しいデバイスをネットワークに接続する方法について別途合意する必要はありません。

各国には標準の軌間があります。これにより、レールを敷設するエンジニアリング会社と、そのレール上を走る列車を製造するエンジニアリング会社との分業が可能になり、鉄道会社はシステム全体を再設計することなく、列車の交換やアップグレードを行うことができます。

ビジネスがクライアントに提示するサービスは、インターフェイスとして説明できます。明確に定義されたインターフェイスは、サービスを強調し、手段を隠します。手紙をメールボックスに入れるとき、郵便システムが所定の時間内に手紙を配達することを期待しますが、手紙がどのように配達されるかについては期待していません: 知る必要はなく、郵便サービスには柔軟性があります要件と現在の状況に最も適した配送手段を選択してください。これに対する例外は、顧客が航空便を選択できることです。これは、実装があまりにも多く明らかになるため、現代のコンピューター プログラマーが設計する種類のインターフェイスではありません。

自然からの例: 私は、eats()、makeSound()、moves() などの例にあまり熱心ではありません。彼らは動作を説明していますが、それは正しいですが、相互作用とそれらがどのように有効化されているかについては説明していません。自然界での相互作用を可能にするインターフェースの明白な例は、生殖に関するものです。たとえば、花はミツバチに特定のインターフェースを提供して、受粉が行われるようにします。

于 2009-01-14T20:07:22.580 に答える
6

一生を .net 開発者として過ごし、独自のインターフェイスをまったく作成しないという可能性は十分にあります。結局のところ、私たちは何十年もの間、それらがなくても問題なく生き残り、私たちの言語はまだチューリング完全でした.

インターフェイスが必要な理由はわかりませんが、現在のプロジェクトでインターフェイスを使用する場所のリストを提供できます。

  1. 私たちのプラグイン モデルでは、インターフェースごとにプラグインをロードし、そのインターフェースをプラグイン作成者に提供して準拠させます。

  2. マシン間メッセージング システムでは、すべてのメッセージ クラスが特定のインターフェイスを実装し、そのインターフェイスを使用して「ラップ解除」されます。

  3. 当社の構成管理システムは、構成設定の設定および取得に使用されるインターフェースを定義します。

  4. 厄介な循環参照の問題を回避するために使用するインターフェイスが 1 つあります。(必要がない場合は、これを行わないでください。)

ルールがあるとすれば、複数のクラスを is-a 関係でグループ化したいが、基本クラスに実装を提供したくない場合は、インターフェイスを使用することだと思います。

于 2009-01-14T19:12:11.570 に答える
5

コード例 (Andrew のものと what-is-the-purpose-of-interfaces の余分なものを組み合わせたもの) は、多重継承をサポートしていない言語 (c# およびジャバ):

interface ILogger
{
    void Log();
}
class FileLogger : ILogger
{
    public void Log() { }
}
class DataBaseLogger : ILogger
{
    public void Log() { }
}
public class MySpecialLogger : SpecialLoggerBase, ILogger
{
    public void Log() { }
}

FileLogger と DataBaseLogger はインターフェイスを必要としないことに注意してください (Logger 抽象基本クラスである可能性があります)。ただし、基本クラスの使用を強制するサードパーティのロガーを使用する必要があると考えてください (使用する必要がある保護されたメソッドを公開するとしましょう)。この言語は多重継承をサポートしていないため、抽象基本クラスのアプローチを使用することはできません。

肝心なのは、コードの柔軟性を高めるために、可能な場合はインターフェイスを使用することです。あなたの実装はあまり縛られていないので、変更により適しています。

于 2009-03-20T18:49:35.020 に答える
4

クラスの動作を強制する必要がある場合は、インターフェイスを定義する必要があります。

動物の行動には、歩く、食べる、走るなどが含まれる場合があります。したがって、それらをインターフェイスとして定義します。

もう 1 つの実用的な例は、ActionListener (または Runnable) インターフェイスです。特定のイベントを追跡する必要がある場合は、それらを実装します。actionPerformed(Event e)したがって、クラス (またはサブクラス) でメソッドの実装を提供する必要があります。同様に、Runnable インターフェースの場合、public void run()メソッドの実装を提供します。

また、これらのインターフェイスを任意の数のクラスで実装できます。

インターフェイスが (Java で) 使用されるもう 1 つの例は、C++ で提供される多重継承を実装することです。

于 2009-01-14T19:13:07.463 に答える
4

私は時々インターフェースを使用してきましたが、これが私の最新の使用法です(名前は一般化されています):

ビジネス オブジェクトにデータを保存する必要がある WinForm にカスタム コントロールが多数あります。1 つの方法は、各コントロールを個別に呼び出すことです。

myBusinessObject.Save(controlA.Data);
myBusinessObject.Save(controlB.Data);
myBusinessObject.Save(controlC.Data);

この実装の問題は、コントロールを追加するたびに、「データの保存」メソッドに移動して新しいコントロールを追加する必要があることです。

SaveToBusinessObject(...) メソッドを持つ ISaveable インターフェイスを実装するようにコントロールを変更したので、「データの保存」メソッドはコントロールを反復処理し、ISaveable であるものが見つかった場合は SaveToBusinessObject を呼び出します。したがって、新しいコントロールが必要になったとき、誰かがしなければならないことは、そのオブジェクトに ISaveable を実装することだけです (別のクラスには触れないでください)。

foreach(Control c in Controls)
{
  ISaveable s = c as ISaveable;

  if( s != null )
      s.SaveToBusinessObject(myBusinessObject);
}

多くの場合、インターフェイスの実現されていない利点は、変更をローカライズできることです。一度定義すると、アプリケーションの全体的なフローを変更することはほとんどありませんが、詳細レベルで変更を加えることがよくあります。詳細を特定のオブジェクトに保持すると、ProcessA の変更は ProcessB の変更に影響しません。(基本クラスにもこの利点があります。)

編集: もう 1 つの利点は、アクションの特異性です。私の例のように、やりたいことはデータを保存することだけです。コントロールの種類や、それ以外のことができるかどうかは気にしません。コントロールにデータを保存できるかどうかを知りたいだけです。これにより、保存コードがかなり明確になります。カスタム コントロールがすべてを処理するため、それがテキスト、数値、ブール値などであるかどうかを確認するチェックはありません。

于 2009-01-14T19:52:09.960 に答える
2

.NET Frameworkアセンブリを参照し、標準オブジェクトの基本クラスにドリルダウンすると、多くのインターフェイス(ISomeNameという名前のメンバー)に気付くでしょう。

インターフェイスは基本的に、大小を問わず、フレームワークを実装するためのものです。自分のフレームワークを書きたいと思うまで、インターフェースについても同じように感じました。また、インターフェイスを理解することで、フレームワークをより迅速に学習できることもわかりました。ほぼすべてのことに対してよりエレガントなソリューションを書きたいと思った瞬間、インターフェースが非常に理にかなっていることに気付くでしょう。それは、クラスに仕事に適した服を着させる方法のようなものです。さらに重要なことに、クラスがインターフェイスを実装すると複雑なオブジェクトの複雑さが軽減され、機能の分類に役立つため、インターフェイスによってシステムの自己文書化が大幅に向上します。

クラスは、明示的または暗黙的にフレームワークに参加できるようにする場合にインターフェイスを実装します。たとえば、IDisposableは、一般的で便利なDispose()メソッドのメソッドシグネチャを提供する一般的なインターフェイスです。フレームワークでは、クラスについて知っておく必要があるのは、クラスがIDisposableを実装している場合、クリーンアップの目的で((IDisposable)myObject).Dispose()を呼び出すことができることだけです。

古典的な例:IDisposableインターフェイスを実装しないと、C#で「using()」キーワード構造を使用できません。これは、パラメーターとして指定されたオブジェクトをIDisposableに暗黙的にキャストできる必要があるためです。

複雑な例:より複雑な例は、System.ComponentModel.Componentクラスです。このクラスは、IDisposableとIComponentの両方を実装します。すべてではないにしても、ビジュアルデザイナが関連付けられているほとんどの.NETオブジェクトは、IDEがコンポーネントと対話できるようにIComponentを実装しています。

結論:.NET Frameworkに慣れてくると、オブジェクトブラウザーまたは.NET Reflector(無料)ツール(http://www.red-gate.com )で新しいクラスに遭遇したときに最初に行うことです。 / products / reflector /)は、継承元のクラスと、実装するインターフェイスを確認するためのものです。.NET Reflectorは、派生クラスも表示できるため、オブジェクトブラウザよりも優れています。これにより、特定のクラスから派生したすべてのオブジェクトについて学習できるため、存在を知らなかったフレームワーク機能について学習できる可能性があります。これは、更新された名前空間または新しい名前空間が.NETFrameworkに追加された場合に特に重要です。

于 2009-01-14T22:31:06.410 に答える
2

また、モックユニットテスト(.Net)を実行することもできます。クラスでインターフェイスを使用している場合は、単体テストでオブジェクトをモックし、ロジックを簡単にテストできます(データベースやWebサービスなどに実際にアクセスする必要はありません)。

http://www.nmock.org/

于 2009-01-14T22:36:42.063 に答える
2

最も簡単な例は、支払い処理業者 (Paypal、PDS など) のようなものです。

ProcessACH および ProcessCreditCard メソッドを持つインターフェイス IPaymentProcessor を作成するとします。

具体的な Paypal 実装を実装できるようになりました。これらのメソッドに PayPal 固有の関数を呼び出させる。

後で別のプロバイダーに切り替える必要があると判断した場合は、そうすることができます。新しいプロバイダーの別の具体的な実装を作成するだけです。あなたが結び付けられているのはあなたのインターフェース(コントラクト)だけなので、それを消費するコードを変更することなく、アプリケーションが使用するものを交換できます。

于 2009-01-14T19:13:42.377 に答える
2

一人称シューティング ゲームを作成しているとします。プレイヤーは複数の銃から選択できます。

Gun関数を定義するインターフェースを持つことができますshoot()

クラスのさまざまなサブクラス、GunつまりShotGun Sniperなどが必要です。

ShotGun implements Gun{
    public void shoot(){
       \\shotgun implementation of shoot.
    } 
}

Sniper implements Gun{
    public void shoot(){
       \\sniper implementation of shoot.
    } 
}

シュータークラス

射手はアーマーにすべての銃を持っています。それを表すを作成しましょうList

List<Gun> listOfGuns = new ArrayList<Gun>();

射手は、関数を使用して、必要に応じて銃を循環させます。switchGun()

public void switchGun(){
    //code to cycle through the guns from the list of guns.
    currentGun = //the next gun in the list.
}

上記の関数を使用して現在の Gun を設定し、 が呼び出されたshoot()ときに関数を呼び出すだけfire()です。

public void fire(){
    currentGun.shoot();
}

シュート機能の動作は、インターフェイスの実装によって異なりGunます。

結論

クラス関数が、実装されたクラスのインスタンス(オブジェクト)に基づいて、その動作を変更する対象となる別のクラスの関数に依存している場合、インターフェイスを作成します。

たとえばfire()、クラスの関数は、 Shooterguns( SniperShotGun) が関数を実装することを期待していshoot()ます。ですから、銃を切り替えて発砲します。

shooter.switchGun();
shooter.fire();

fire()関数の動作を変更しました。

于 2013-07-15T17:53:05.900 に答える
1

ライブラリ開発者(他のコーダーのためにコーディングする人)になると、インターフェースが明らかになります。私たちのほとんどは、既存のAPIとプログラミングライブラリを使用するアプリケーション開発者として始まります。

インターフェイスがコントラクトであるのと同じように、インターフェイスがコードの一部を安定させるための優れた方法であるとはまだ誰も言及していません。これは、チームプロジェクトの場合(または他の開発者が使用するコードを開発している場合)に特に役立ちます。だから、ここにあなたのための具体的なシナリオがあります:

チームでコードを開発しているとき、他の人があなたが書いたコードを使用している可能性があります。彼らがあなたの(安定した)インターフェースにコーディングするとき、彼らは最も幸せになるでしょう、そしてあなたがあなたのチームのコードを壊すことなくあなたの実装(インターフェースの後ろに隠される)を変更する自由があるときあなたは幸せになるでしょう。これは情報隠蔽の変形です(インターフェースは公開されており、実装はクライアントプログラマーから隠されています)。保護されたバリエーションの詳細をご覧ください。

インターフェイスへのコーディングに関するこの関連する質問も参照してください。

于 2012-11-28T20:41:02.800 に答える
1

インターフェイスを使用する目的は非常に多くあります。

  1. ポリモーフィック動作で使用します。子クラスへの参照を持つインターフェイスを使用して、子クラスの特定のメソッドを呼び出したい場所。

  2. 必要に応じてすべてのメソッドを実装するためのクラスとのコントラクトを持ちます。最も一般的な使用法は、インターフェイスを継承する DLL でラッパー クラスが生成される COM オブジェクトです。これらのメソッドはバックグラウンドで呼び出され、それらを実装する必要がありますが、COM DLL で定義されているのと同じ構造を使用して、それらが公開するインターフェイスを介してのみ知ることができます。

  3. 特定のメソッドをクラスにロードすることにより、メモリ使用量を削減します。3 つのビジネス オブジェクトがあり、それらが 1 つのクラスに実装されている場合と同様に、3 つのインターフェイスを使用できます。

例: IUser、IOrder、IOrderItem

public interface IUser()
{

void AddUser(string name ,string fname);

}

// Same for IOrder and IOrderItem
//


public class  BusinessLayer: IUser, IOrder, IOrderItem

{    
    public void AddUser(string name ,string fname)
    {
        // Do stuffs here.
    }

    // All methods from all interfaces must be implemented.

}

ユーザーのみを追加する場合は、次のようにします。

IUser user = new (IUser)BusinessLayer();

// It will load  all methods into memory which are declared in the IUser interface.

user.AddUser();
于 2009-06-24T11:37:04.233 に答える
1

インターフェイスは通常、オブジェクトが実行できる動作を定義する場合に使用されます。

.NET の世界でのこの好例はIDisposableインターフェイスです。これは、手動で解放する必要があるシステム リソースを使用する Microsoft クラスで使用されます。それを実装するクラスには Dispose() メソッドが必要です。

( Dispose() メソッドは、VB.NETおよびC#の using 言語構造によっても呼び出され、sでのみ機能しますIDisposable)

TypeOf ... Is(VB.NET)、is(C#)、instanceof(Java)などの構成を使用して、オブジェクトが特定のインターフェイスを実装しているかどうかを確認できることに注意してください。

于 2009-01-14T20:02:10.953 に答える
1

おそらくすでに何人かが答えているように、インターフェースを使用して、クラス間で特定の動作を強制することができますが、これらの動作は同じ方法で実装されません。したがって、インターフェースを実装することにより、クラスにインターフェースの動作があると言っています。IAnimal インターフェイスは典型的なインターフェイスではありません。Dog、Cat、Bird などのクラスは動物のタイプであり、おそらくそれを継承する必要があるためです。これは継承のケースです。代わりに、この場合のインターフェースは、IRunnable、IFlyable、ITrainable などの動物の動作に似ています。

インターフェースは多くの点で優れていますが、重要なものの 1 つはプラグ可能性です。たとえば、List パラメーターを持つメソッドを宣言すると、List インターフェースを実装するすべてのものを渡すことができるため、開発者は大量のコードを書き直すことなく、後で別のリストを削除してプラグインすることができます。

インターフェイスをまったく使用しない可能性もありますが、プロジェクトを最初から設計している場合、特に何らかのフレームワークを設計している場合は、インターフェイスに慣れる必要があります。

Coad、Mayfield、および Kern によるJava Designのインターフェースに関する章を読むことをお勧めします。彼らは、平均的な紹介テキストよりも少し上手に説明しています。Java を使用していない場合は、主に概念である章の冒頭を読むだけでかまいません。

于 2009-01-14T20:03:05.057 に答える
1

ラーセナルが言ったことを拡張する。インターフェイスは、すべての実装クラスが従わなければならない契約です。このため、プログラミングと呼ばれる手法をコントラクトに使用できます。これにより、ソフトウェアは実装に依存しなくなります。

于 2009-01-14T19:07:28.520 に答える
1

システムに柔軟性を追加するプログラミング技術と同様に、インターフェイスもある程度の複雑さを追加します。多くの場合、それらは優れており、どこでも使用できます (すべてのクラスのインターフェイスを作成できます)。ただし、そうすると、より複雑なシステムが作成され、保守が難しくなります。

いつものように、ここにはトレードオフがあります: 保守性よりも柔軟性です。どちらがより重要ですか? 答えはありません。プロジェクトによって異なります。ただし、すべてのソフトウェアを維持する必要があることを覚えておいてください...

したがって、私のアドバイスは、本当に必要になるまでインターフェースを使用しないことです。(Visual Studio を使用すると、既存のクラスから 2 秒でインターフェイスを抽出できます。急いではいけません。)

そうは言っても、いつインターフェイスを作成する必要がありますか?

2 つ以上の同様のクラスを突然処理する必要があるメソッドをリファクタリングするときに、これを行います。次に、インターフェイスを作成し、このインターフェイスを 2 つ (またはそれ以上) の類似したクラスに割り当て、メソッド パラメーターの型を変更します (クラスの型をインターフェイスの型に置き換えます)。

そしてそれは動作します:o)

1 つの例外: オブジェクトをモックする場合、インターフェイスははるかに使いやすくなります。そのため、私はこのためだけにインターフェースを作成することがよくあります。

PS : 「インターフェイス」と書くときは、純粋なインターフェイス クラスを含む「任意の基本クラスのインターフェイス」を意味します。抽象クラスは、ロジックを追加できるため、多くの場合、純粋なインターフェイスよりも優れていることに注意してください。

よろしく、シルヴァン。

于 2009-01-14T20:30:42.877 に答える