わかりました、私の友人はプログラミングで「インターフェイス」が何を意味するかについて行き来します。
「インターフェース」の最良の説明は何ですか。
私にとってインターフェースはクラスの青写真です、これが最良の定義ですか?
インターフェースは、開発中の過負荷でわかりにくい用語の1つです。
実際には、抽象化とカプセル化の概念です。与えられた「ボックス」に対して、それは宣言そのボックスの「入力」と「出力」です。ソフトウェアの世界では、通常、ボックスで(引数とともに)呼び出せる操作と、場合によってはこれらの操作の戻り値の型を意味します。
それがしないのは、これらの操作のセマンティクスが何であるかを定義することですが、宣言の近くで(コメントなどを介して)それらを文書化するか、適切な命名規則を選択することは一般的です(そして非常に良い習慣です)。それにもかかわらず、これらの意図が守られるという保証はありません。
アナロジーは次のとおりです。テレビがオフのときにテレビを見てみましょう。そのインターフェイスは、ボタン、さまざまなプラグ、画面です。そのセマンティクスと動作は、入力(ケーブルプログラミングなど)を受け取り、出力(画面への表示、音声など)を取得することです。ただし、プラグインされていないテレビを見ると、予想されるセマンティクスをインターフェイスに投影しています。知っているすべての人にとって、テレビは電源を入れると爆発する可能性があります。しかし、その「インターフェイス」に基づいて、水の摂取量がないため、コーヒーを作れないと仮定できます。
オブジェクト指向プログラミングでは、通常、インターフェイスは、そのインターフェイスを持つクラスのインスタンスが応答できるメソッド(またはメッセージ)のセットを定義します。
さらに混乱を招くのは、Javaのような一部の言語には、その言語固有のセマンティクスとの実際のインターフェースがあるということです。たとえば、Javaでは、実装のないメソッド宣言のセットですが、インターフェイスも型に対応し、さまざまな入力規則に従います。
C++などの他の言語では、インターフェイスがありません。クラス自体はメソッドを定義しますが、クラスのインターフェースは非プライベートメソッドの宣言と考えることができます。 C++のコンパイル方法により、実際の実装なしでクラスの「インターフェース」を持つことができるヘッダーファイルを取得します。 Javaインターフェースを純粋な仮想関数などの抽象クラスと模倣することもできます。
インターフェイスは、クラスの青写真ではないことは間違いありません。ブループリントは、1つの定義では「詳細な行動計画」です。インターフェイスはアクションについて何も約束しません!混乱の原因は、ほとんどの言語で、メソッドのセットを定義するインターフェイスタイプがある場合、それを実装するクラスが同じメソッドを「繰り返し」(定義を提供する)、インターフェイスがスケルトンまたはクラスの概要。
次の状況を考慮してください。
ゾンビが突然あなたを攻撃するとき、あなたは大きな空の部屋の真ん中にいます。
武器はありません。
幸いなことに、生きている仲間が部屋の戸口に立っています。
「クイック!」あなたは彼に叫ぶ。 「ゾンビを攻撃できるものを投げてください!」
今考慮してください:
あなたは正確に指定しませんでした(または気にしません)what友達が投げることを選択します。
...しかし、それは問題ではありません:
can投げられるものです(彼はあなたにソファを投げることはできません)
手に入れることができるものです(手裏剣を投げないようにしましょう)
それはあなたがゾンビの脳を打ち負かすために使用できるものです(それは枕などを排除します)
野球のバットを手に入れてもハンマーを手に入れても構いません-
3つの条件を実装している限り、問題ありません。
要約すると:
インターフェイスを作成するとき、基本的に「何か必要な...」と言っています。
インターフェースは、あなたが実装者であるかユーザーであるかに応じて、従うべき、または与えられるべき契約です。
「青写真」は使用するのに適したWordではないと思います。設計図は、何かを構築する方法を示します。インターフェイスは、何かを構築する方法を伝えることを特に避けます。
インターフェースは、クラスと対話する方法、つまりサポートするメソッドを定義します。
私にとってインターフェースはクラスの青写真です、これが最良の定義ですか?
いいえ。ブループリントには通常、内部構造が含まれます。しかし、インターフェースとは、純粋にクラスの外側に見えるもの、より正確には、インターフェースを実装するクラスのファミリーに関するものです。
インターフェイスは、メソッドのシグネチャと定数の値で構成され、インターフェイスを実装するクラスとそれを使用する他のクラス間の(通常は非公式の)「動作規約」でもあります。
プログラミングでは、インターフェイスはオブジェクトの動作を定義しますが、実際には動作を指定しません。特定のクラスが何かを行えることを保証するのは契約です。
ここでこのC#コードを検討してください。
using System;
public interface IGenerate
{
int Generate();
}
// Dependencies
public class KnownNumber : IGenerate
{
public int Generate()
{
return 5;
}
}
public class SecretNumber : IGenerate
{
public int Generate()
{
return new Random().Next(0, 10);
}
}
// What you care about
class Game
{
public Game(IGenerate generator)
{
Console.WriteLine(generator.Generate())
}
}
new Game(new SecretNumber());
new Game(new KnownNumber());
Gameクラスには秘密の番号が必要です。それをテストするために、秘密番号として使用されるものを注入したいと思います(この原則は、Inversion of Controlと呼ばれます)。
ゲームクラスは、実際に乱数を作成するものについて「オープンマインド」になりたいため、コンストラクターで「Generateメソッドを持つもの」を要求します。
まず、インターフェイスは、オブジェクトが提供する操作を指定します。見た目だけが含まれていますが、実際の実装は示されていません。これはメソッドの署名です。従来、C#インターフェースでは、接頭辞にIが付いています。クラスはIGenerateインターフェースを実装するようになりました。つまり、コンパイラーは、両方にintを返し、Generate
と呼ばれるメソッドがあることを確認します。ゲームは2つの異なるオブジェクトと呼ばれ、それぞれが正しいインターフェイスを実装しています。他のクラスは、コードの構築時にエラーを生成します。
ここで、私はあなたが使用した青写真の類推に気づきました:
クラスは、一般的にオブジェクトの青写真と見なされます。インターフェイスはクラスが行う必要があることを指定するため、それは実際にはクラスの単なる青写真であると主張することができますが、クラスは必ずしもインターフェイスを必要としないので、この比metaは壊れていると主張します。インターフェイスを契約と考えてください。 「署名」するクラスは、契約の条件に準拠するために法的に必要です(コンパイラーの警察によって施行されます)。これは、インターフェースで指定されていることを行う必要があることを意味します。
これはすべて、OOまたはC#の場合のように、一部のJava言語の静的に型付けされた性質によるものです。一方、Pythonでは、別のメカニズムが使用されます。
import random
# Dependencies
class KnownNumber(object):
def generate(self):
return 5
class SecretNumber(object):
def generate(self):
return random.randint(0,10)
# What you care about
class SecretGame(object):
def __init__(self, number_generator):
number = number_generator.generate()
print number
ここでは、どのクラスもインターフェースを実装していません。 Pythonは、SecretGame
クラスが渡されたオブジェクトを呼び出そうとするだけなので、気にしません。オブジェクトにgenerate()メソッドがある場合は、すべて正常です。そうでない場合:KAPUTT!この間違いはコンパイル時には見られませんが、実行時に見られるので、おそらくプログラムが既にデプロイされ実行されているときに見られます。 C#は、それに近づく前に通知します。
OO言語では自然に関数は第一級の市民ではないため、このメカニズムが使用される理由は、単純に述べられています。ご覧のとおり、KnownNumber
とSecretNumber
には、数値を生成するための関数が含まれています。実際にはクラスはまったく必要ありません。したがって、Pythonでは、それらを捨てて、独自に関数を選択できます。
# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())
# Functional Approach
# Dependencies
class SecretGame(object):
def __init__(self, generate):
number = generate()
print number
SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)
ラムダは単なる関数であり、「インラインで、あなたが行くように」宣言されました。デリゲートはC#でも同じです:
class Game
{
public Game(Func<int> generate)
{
Console.WriteLine(generate())
}
}
new Game(() => 5);
new Game(() => new Random().Next(0, 10));
Javaは他の2つ(PythonとC#)ができるように関数をいじることができないため、後者の例はJavaでこのようにはできません。そこでは、インターフェースは、AVでこのように動作を特定する唯一の方法です。
技術的には、インターフェイスを、オブジェクトと対話するための一連の方法(メソッド、プロパティ、アクセサ...語彙は使用している言語に依存します)として説明します。オブジェクトがインターフェイスをサポート/実装する場合、インターフェイスで指定されたすべての方法を使用して、このオブジェクトと対話できます。
意味的には、インターフェイスには、ユーザーが実行できるかどうかに関する規則(たとえば、メソッドを呼び出す順序)と、そのやり取りを前提としてオブジェクトの状態について引き受けることができる規則を含めることもできます。遠い。
インターフェースは、メソッドが「どのように」ではなく「どのような仕事」であるかです。それは契約です。優先キューのように、あなたはそれをどうするかを知っていますが、基礎となる実装は知りません。クラスは、既存の操作の「効果」を変更しないことに同意し、クライアントは、インターフェイスに基づいてクラスを厳密に使用し、実装の詳細を無視することに同意します。
レイマン例:テレビを制御できるユニバーサルリモコンを考えてみてください。古いチューブモデルでも、LCDまたはプラズマスクリーンを使用するテレビでもかまいません。 2、5、Enterの順に押すと、チャンネル25が表示されますが、そのためのメカニズムは基盤となるテクノロジーによって大きく異なります。
個人的には、テンプレートのようなインターフェースがあります。インターフェイスにメソッドfoo()およびbar()の定義が含まれている場合、このインターフェイスを使用するすべてのクラスにメソッドfoo()およびbar()があることがわかります。
男(ユーザーまたはオブジェクト)が何らかの仕事をしたいと考えているとしましょう。彼は、企業(実装されたクラスを使用して作成された実世界のオブジェクト)と契約する中間者(インターフェース)に連絡します。いくつかのタイプの作品が彼によって定義され、どの企業がそれを実装して結果を出します。すべての企業が独自の方法で作業を実施しますが、結果は同じです。このように、ユーザーは単一のインターフェイスを使用して作業を完了します。 Interfaceは、実装する内部サブシステムによって内部的に定義されるコマンドがほとんどないシステムの目に見える部分として機能すると思います。
私の意見では、インターフェースはJavaで一般的に関連付けられているものよりも広い意味を持っています。 「インターフェース」は、モジュールの制御/監視を可能にするいくつかの一般的な機能を備えた利用可能な操作のセットとして定義します。
この定義では、クライアントがモジュールであるプログラムインターフェイスとヒューマンインターフェイス(GUIなど)の両方をカバーしようとします。
他の人がすでに言ったように、インターフェイスには、入力と出力の点で、常に何らかの契約があります。インターフェイスは、操作の「方法」について何も約束しません。現在の状態、選択された操作、およびそのパラメーターが与えられると、結果の一部のプロパティのみが保証されます。
上記のように、「契約」と「プロトコル」の同義語が適切です。
このインターフェイスは、クラスによって公開されることが予想されるメソッドとプロパティで構成されます。
したがって、クラスCheetos Bag
がChip Bag
インターフェイスを実装する場合、Cheetos Bag
が他のChip Bag
とまったく同じように動作することを期待する必要があります。 (つまり、.attemptToOpenWithoutSpillingEverywhere()
メソッドなどを公開します。)
従来の定義-インターフェースは、それを実装するクラスによって実装される必要があるメソッドを指定するコントラクトです。
インターフェイスの定義は時間とともに変化しました。 Interfaceにはメソッド宣言のみがあると思いますか? Javaの後の静的な最終変数とデフォルトの定義はどうですか。
Javaにインターフェースが導入されたのは、複数の継承に関するDiamondの問題のためであり、それが実際に意図していることです。
インターフェースは、多重継承の問題を回避するために作成された構造体であり、抽象メソッド、デフォルト定義、静的な最終変数を持つことができます。
インターフェイスは、クラスの操作を内部の実装から分離します。したがって、一部の実装では、多くのインターフェイスを提供できます。
通常、人々はそれをクラスのメソッドで利用できるものの「契約」と表現します。
実装を決定することになるため、これは絶対に青写真ではありません。完全なクラス定義は、青写真と言えるでしょう。
インターフェースは、それを継承するクラスが実装しなければならないものを定義します。このようにして、複数のクラスがインターフェイスから継承でき、その継承のために、次のことができます。
詳細については、こちらをご覧ください http://msdn.Microsoft.com/en-us/library/ms173156.aspx
インターフェイスは、いくつかのOO言語が アドホックポリモーフィズム を達成する方法です。アドホックポリモーフィズムは、異なるタイプで動作する同じ名前の単なる関数です。
要するに、インターフェイスが解決しようとしている基本的な問題は、私たちが何かをどのように使用するかを、それをどのように実装するかから分離することです。ただし、インターフェイス コントラクトではない を考慮する必要があります。続きを読む こちら 。