私は開発の学習段階にいるので、インターフェイスについてさらに学ぶ必要があると感じています。
私は頻繁にそれらについて読みますが、私はそれらを把握できないようです。
「ウォーク」、「ラン」、「GetLegs」などのIAnimalインターフェイスを備えた動物の基本クラスなどの例を読んでいますが、何かに取り組んだことがなく、「ちょっとインターフェイスを使うべきだ」と感じました。ここに!"
私は何が欠けていますか?なぜ把握するのがそんなに難しい概念なのでしょう!私は、その必要性を具体的に理解することができないかもしれないという事実に怖がっています-主にそれらを理解するためのいくつかの欠落した側面のために!開発者であるという点で何かが欠けているように感じます!誰かがこのような経験をし、ブレークスルーを経験したことがあるなら、この概念を理解する方法についてのいくつかのヒントをいただければ幸いです。ありがとうございました。
この具体的な問題を解決します。
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など)を定義できます。
私はジミーの回答がとても好きですが、それに何かを追加する必要があると感じています。全体の鍵は、IProcess ableの「可能」です。これは、インターフェイスを実装するオブジェクトの機能(またはプロパティですが、C#プロパティの意味ではなく「本質的な品質」を意味します)を示します。 IAnimalはおそらくインターフェイスの良い例ではありませんが、システムに歩くことができるものがたくさんある場合、IWalkableは良いインターフェイスになるかもしれません。犬、牛、魚、ヘビなど、動物から派生したクラスがある場合があります。最初の2つはおそらくIWalkableを実装し、後の2つは歩かないので、歩きません。ここで、「犬と牛が由来する別のスーパークラス、WalkingAnimalだけではないのはなぜですか?」答えは、ロボットなど、歩くこともできる継承ツリーの完全に外側にあるものがある場合です。ロボットはIWalkableを実装しますが、おそらくAnimalから派生しません。歩くことができるもののリストが必要な場合は、IWalkableとして入力し、すべての歩行動物とロボットをリストに入れることができます。
ここで、IWalkableをIPersistableのようなよりソフトウェア的なものに置き換えれば、実際のプログラムで見られるものにずっと似たものになります。
同じ機能の実装が異なる場合は、インターフェイスを使用します。
共通の具体的な実装を共有する必要がある場合は、抽象/基本クラスを使用します。
契約のようなインターフェースを考えてください。 「これらのクラスは、これらの一連のルールに従う必要があります」と言う方法です。
そのため、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();
}
インターフェイスに対してプログラミングすることにより、インターフェイスの意図を実装するクラスを本質的に信頼します。したがって、この例では、「私は気にしないhow彼らが走り歩く限り、彼らは走り歩く。私のRunThenWalkは彼らがその合意を満たす限り有効です。クラスについて他に何も知らなくても完全に機能します。」
この関連する質問 にも良い議論があります。
そんなに心配しないでください。多くの開発者が、インターフェースを作成する必要はほとんどありません。 。NET フレームワーク内で使用可能なインターフェイスを頻繁に使用しますが、すぐに作成する必要性を感じない場合、それについて驚くべきことは何もありません。
私がいつも誰かにあげる例は、SailboatクラスとViperクラスがある場合です。これらは、それぞれBoatクラスとCarクラスを継承します。ここで、これらすべてのオブジェクトをループして、Drive()
メソッドを呼び出す必要があると言います。次のようなコードを書くこともできます:
if(myObject is Boat)
((Boat)myObject).Drive()
else
if (myObject is Car)
((Car)myObject).Drive()
書く方がはるかに簡単です:
((IDrivable)myObject).Drive()
複数の型に対して単一の変数を使用できるようにしたいが、それらの型はすべて、インターフェイス宣言を介して同じメソッドを実装する場合、Jimmyにはそれがあります。その後、インターフェイス型変数のメインメソッドを呼び出すことができます。
ただし、インターフェイスを使用するもう1つの理由があります。プロジェクトアーキテクトが実装コーダーとは異なる人物である場合、または複数の実装コーダーと1人のプロジェクトマネージャーがいる場合。担当者は、たくさんのインターフェースを作成して、システムが相互運用することを確認し、それを開発者に任せて実装クラスでインターフェースを埋めることができます。これは、複数の人が互換性のあるクラスを作成し、並行して実行できるようにするための最良の方法です。
私は軍の例えが好きです。
軍曹は、あなたがソフトウェア開発者、ミュージシャン、またはlawyerであるかどうかは気にしません。
あなたは兵士として扱われます。
軍曹が彼が働いている人の特定の詳細に煩わされないように、easier
兵士の抽象化として全員を扱います(...そして、彼らが物事のように振る舞わなかった場合、それらを罰します)。
人が兵士のように振る舞う能力は、ポリモーフィズムと呼ばれます。
インターフェースは、ポリモーフィズムの実現を支援するソフトウェア構成です。
必要性シンプルさを達成するために詳細を抽象化することはあなたの質問に対する答えです。
多態性 は、語源的に「多くの形式」を意味し、基本クラスのサブクラスのオブジェクトを、基本クラスのオブジェクトであるかのように扱う機能です。したがって、基本クラスには多くの形式があります。基本クラス自体とそのサブクラスです。
(..)これにより、コードが記述しやすくなり、他の人が理解しやすくなります。また、他のサブクラスを後でタイプファミリに追加でき、それらの新しいサブクラスのオブジェクトも既存のコードで動作するため、コードを拡張可能にします。
私の経験では、モックフレームワークでユニットテストを開始するまで、インターフェイスを作成する原動力は発生しませんでした。インターフェイスを使用すると、モック作成がはるかに簡単になります(フレームワークが仮想メソッドに依存しているため)。始めてみると、実装からクラスへのインターフェイスを抽象化することの価値がわかりました。実際のインターフェースを作成しなくても、メソッドを仮想化するようにしています(オーバーライドできる暗黙的なインターフェースを提供しています)。
インターフェースへのリファクタリングの優れた実践を強化することがわかった他の多くの理由がありますが、ユニットテスト/モックのことは、実際の経験の最初の「アハモーメント」を提供したものでした。
[〜#〜] edit [〜#〜]:明確にするために、ユニットテストとモックでは、実際に具体的な実装とテストで使用される代替モック実装の2つの実装が常にあります。実装が2つあると、インターフェースの価値が明らかになります。インターフェースの観点から対処することで、いつでも実装を置き換えることができます。この場合、私はそれを模擬インターフェースに置き換えます。クラスが適切に構築されている場合、実際のインターフェイスなしでこれを行うことができることを知っていますが、実際のインターフェイスを使用するとこれが強化され、よりきれいになります(読者にとって明確です)。この推進力がなければ、ほとんどのクラスだけが、具体的な実装を1つしか持たないため、インターフェイスの価値を高く評価したとは思いません。
プログラミングでのインターフェイスの適切な使用法を確認するのに役立つ可能性のある非プログラミングの例。
電気機器と電気ネットワークの間にはインターフェースがあります。プラグとソケットの形状と、それらを横切る電圧/電流については、規則のセットです。新しい電気機器を実装する場合、プラグがルールに従っている限り、ネットワークからサービスを取得できます。これにより、拡張性が非常に簡単になり、削除されます。または調整のコストが下がります:新しいデバイスがどのように機能し、別の契約を結ぶかについて電力会社に通知する必要はありません。新しいデバイスをネットワークに接続する方法について。
国には標準のレールゲージがあります。これにより、Railsを置くエンジニアリング会社と、それらのRailsで実行する列車を構築するエンジニアリング会社との間で労働区分が可能になり、鉄道会社が交換とアップグレードシステム全体を再構築せずにトレーニングします。
ビジネスがクライアントに提示するサービスは、インターフェースとして記述することができます:明確に定義されたインターフェースサービスを強調し、手段を隠します。メールボックスに手紙を入れると、郵便システムが所定の時間内に手紙を配達することを期待しますが、手紙がどのように配達されるかについての期待はありません:知る必要はありません郵便サービスには、要件と現在の状況に最適な配達の手段を選択する柔軟性があります。これの例外は、顧客がエアメールを選択できることです。これは、実装が多すぎることを明らかにするため、現代のコンピュータープログラマーが設計するようなインターフェースではありません。
自然からの例:私はeats()、makesSound()、moves()などの例にあまり熱心ではありません。彼らは行動を記述していますが、これは正しいですが、そうではありません相互作用とそれらがどのように有効化されるかを記述してください。自然界での相互作用を可能にするインターフェースの明白な例は、繁殖に関するものです。例えば、花は、受粉が行われるように、蜂に特定のインターフェースを提供します。
コード例(Andrew'sと私の追加の what-is-the-purpose-of-interfaces を組み合わせたもの)、これはまた、多重継承のサポート(c#およびJava):
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抽象基本クラスの場合もあります)。ただし、基本クラスを使用することを強制するサードパーティのロガーを使用する必要があることを考慮してください(使用する必要がある保護されたメソッドを公開するとしましょう)。この言語は多重継承をサポートしていないため、抽象基本クラスのアプローチを使用することはできません。
結論として、可能な場合はインターフェイスを使用して、コードの柔軟性を高めます。実装の結び付きが少ないため、変更に適しています。
.net開発者として一生をかけて、独自のインターフェイスを作成することはまったく不可能です。結局、私たちは何十年もそれらなしでうまく生き残ったし、私たちの言語はチューリング完全でした。
インターフェイスが必要な理由を説明することはできませんが、現在のプロジェクトでインターフェイスを使用する場所のリストを提供できます。
プラグインモデルでは、インターフェイスごとにプラグインを読み込み、準拠するプラグインライターにそのインターフェイスを提供します。
マシン間メッセージングシステムでは、メッセージクラスはすべて特定のインターフェイスを実装し、そのインターフェイスを使用して「ラップ解除」されます。
構成管理システムは、構成設定を設定および取得するために使用されるインターフェイスを定義します。
厄介な循環参照の問題を回避するために使用するインターフェイスが1つあります。 (必要がない場合は、これをしないでください。)
ルールがある場合、is-a関係内のいくつかのクラスをグループ化するときにインターフェイスを使用することですが、基本クラスで実装を提供したくないと思います。
私は時々インターフェースを使用しました、そして、ここに私の最新の使用法があります(名前は一般化されました):
WinFormには、ビジネスオブジェクトにデータを保存する必要があるカスタムコントロールがたくさんあります。 1つのアプローチは、各コントロールを個別に呼び出すことです。
myBusinessObject.Save(controlA.Data);
myBusinessObject.Save(controlB.Data);
myBusinessObject.Save(controlC.Data);
この実装の問題は、コントロールを追加するたびに、「データの保存」メソッドに移動して新しいコントロールを追加する必要があることです。
メソッドSaveToBusinessObject(...)を持つISaveableインターフェイスを実装するようにコントロールを変更したので、「Save Data」メソッドはコントロールを繰り返し処理し、ISaveableが見つかるとSaveToBusinessObjectを呼び出します。そのため、新しいコントロールが必要になったとき、誰かがしなければならないことは、そのオブジェクトにISaveableを実装することだけです(別のクラスには触れないでください)。
foreach(Control c in Controls)
{
ISaveable s = c as ISaveable;
if( s != null )
s.SaveToBusinessObject(myBusinessObject);
}
多くの場合、インターフェイスの未実現の利点は、変更をローカライズすることです。定義すると、アプリケーションの全体的なフローを変更することはほとんどありませんが、詳細レベルで変更を行うことがよくあります。特定のオブジェクトの詳細を保持する場合、ProcessAの変更はProcessBの変更に影響しません。 (基本クラスもこの利点を提供します。)
編集:別の利点は、アクションの特異性です。私の例のように、やりたいことはデータを保存することだけです。コントロールの種類や、他の操作ができるかどうかは気にしません。コントロールにデータを保存できるかどうかを知りたいだけです。これにより、保存コードが非常に明確になります。カスタムコントロールがすべてを処理するため、テキスト、数値、ブール値などを確認するチェックはありません。
クラスの動作を強制する必要がある場合は、インターフェイスを定義する必要があります。
動物の行動には、歩く、食べる、走るなどが含まれる場合があります。したがって、それらをインターフェースとして定義します。
別の実用的な例は、ActionListener(またはRunnable)インターフェースです。特定のイベントを追跡する必要がある場合に実装します。したがって、クラス(またはサブクラス)でactionPerformed(Event e)
メソッドの実装を提供する必要があります。同様に、Runnableインターフェースの場合、public void run()
メソッドの実装を提供します。
また、これらのインターフェイスを任意の数のクラスで実装できます。
インターフェイスが(Javaで)使用される別のインスタンスは、C++で提供される多重継承を実装することです。
寝ようとするときに発生する可能性のある不快感をモデル化したいとします。
class Mosquito {
void flyAroundYourHead(){}
}
class Neighbour{
void startScreaming(){}
}
class LampJustOutsideYourWindow(){
void shineJustThroughYourWindow() {}
}
あなたが明らかに見ているように、多くの「もの」はあなたが眠ろうとするとき迷惑なことができます。
しかし、これらのクラスの使用に関しては問題があります。共通点はありません。各メソッドを個別に呼び出す必要があります。
class TestAnnoyingThings{
void testAnnoyingThinks(Mosquito mosquito, Neighbour neighbour, LampJustOutsideYourWindow lamp){
if(mosquito != null){
mosquito.flyAroundYourHead();
}
if(neighbour!= null){
neighbour.startScreaming();
}
if(lamp!= null){
lamp.shineJustThroughYourWindow();
}
}
}
この問題を克服するために、インターフェースを導入することができます
interface Annoying{
public void annoy();
}
そして、クラス内に実装します
class Mosquito implements Annoying {
void flyAroundYourHead(){}
void annoy(){
flyAroundYourHead();
}
}
class Neighbour implements Annoying{
void startScreaming(){}
void annoy(){
startScreaming();
}
}
class LampJustOutsideYourWindow implements Annoying{
void shineJustThroughYourWindow() {}
void annoy(){
shineJustThroughYourWindow();
}
}
これにより、これらのクラスの使用がはるかに簡単になります
class TestAnnoyingThings{
void testAnnoyingThinks(Annoying annoying){
annoying.annoy();
}
}
.NET Frameworkアセンブリを参照し、標準オブジェクトの基本クラスにドリルダウンすると、多くのインターフェイス(ISomeNameという名前のメンバー)に気付くでしょう。
インターフェースは、基本的に大規模または小規模のフレームワークを実装するためのものです。独自のフレームワークを作成するまで、インターフェイスについても同じように感じました。また、インターフェイスを理解することで、フレームワークをより迅速に学習できることもわかりました。ほぼ何でもよりエレガントなソリューションを作成したい瞬間に、インターフェイスが非常に理にかなっていることがわかります。クラスに仕事に適した服を着せる方法のようなものです。さらに重要なことは、クラスがインターフェイスを実装すると複雑なオブジェクトがより複雑になり、機能を分類するのに役立つため、インターフェイスを使用するとシステムがより自己文書化できるようになることです。
クラスは、フレームワークに明示的または暗黙的に参加できるようにしたいときに、インターフェースを実装します。たとえば、IDisposableは、一般的で便利なDispose()メソッドのメソッドシグネチャを提供する一般的なインターフェイスです。フレームワークでは、あなたまたは他の開発者がクラスについて知る必要があるのは、IDisposableを実装する場合、クリーンアップのために((IDisposable)myObject).Dispose()を呼び出すことができるということです。
古典的な例:IDisposableインターフェイスを実装しないと、パラメーターとして指定されたオブジェクトを暗黙的にIDisposableにキャストできる必要があるため、C#で「using()」キーワード構成を使用できません。
複雑な例:より複雑な例は、System.ComponentModel.Componentクラスです。このクラスは、IDisposableとIComponentの両方を実装します。すべてではありませんが、ほとんどの場合、ビジュアルデザイナが関連付けられている.NETオブジェクトはIComponentを実装するため、IDEはコンポーネントと対話できます。
結論:.NET Frameworkに慣れてきたら、オブジェクトブラウザーまたは.NET Reflector(無料)ツール内で新しいクラスに遭遇したときに最初に行うこと( http://www.red -gate.com/products/reflector/ )は、継承元のクラスと、それが実装するインターフェイスを確認するためのものです。 .NET Reflectorは、派生クラスも表示できるため、オブジェクトブラウザよりも優れています。これにより、特定のクラスから派生するすべてのオブジェクトについて学習することができます。これにより、存在することを知らなかったフレームワーク機能について学習することができます。これは、更新されたネームスペースまたは新しいネームスペースが.NET Frameworkに追加された場合に特に重要です。
また、モックユニットテスト(.Net)を実行することもできます。クラスがインターフェイスを使用する場合、単体テストでオブジェクトをモックして、ロジックを簡単にテストできます(実際にデータベースやWebサービスなどにアクセスすることなく)。
最も簡単な例は、支払処理業者(Paypal、PDSなど)のようなものです。
ProcessACHおよびProcessCreditCardメソッドを持つインターフェイスIPaymentProcessorを作成するとします。
これで、具体的なPaypal実装を実装できます。これらのメソッドを作成すると、Paypal固有の関数が呼び出されます。
後で別のプロバイダーに切り替える必要がある場合は、できます。新しいプロバイダーの別の具体的な実装を作成するだけです。結び付けられているのはインターフェイス(契約)だけなので、アプリケーションが使用するコードは、それを使用するコードを変更せずに交換できます。
あなたが一人称シューティングゲームを作っていると考えてください。プレイヤーには複数の銃があります。
関数shoot()
を定義するインターフェースGun
を持つことができます。
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();
}
_
Shoot関数の動作は、Gun
インターフェイスの実装によって異なります。
クラス関数が別のクラスの関数に依存している場合、実装されたクラスのインスタンス(オブジェクト)に基づいて動作を変更するインターフェースを作成します。
例えばShooter
クラスのfire()
関数は、guns(Sniper
、ShotGun
)がshoot()
関数を実装することを想定しています。銃を変えて射撃すると.
_shooter.switchGun();
shooter.fire();
_
fire()
関数の動作を変更しました。
通常、インターフェイスは、オブジェクトが示すことができる動作を定義するときに使用されます。
.NETの世界におけるこの良い例は、 IDisposable インターフェイスです。これは、手動で解放する必要があるシステムリソースを使用するMicrosoftクラスで使用されます。それを実装するクラスにDispose()メソッドが必要です。
(Dispose()メソッドは、 VB.NET および C# の使用言語コンストラクトによっても呼び出され、IDisposable
sでのみ機能します)
TypeOf ... Is
(VB.NET)、is
(C#)、instanceof
(Java)などの構造を使用して、オブジェクトが特定のインターフェイスを実装しているかどうかを確認できることに注意してください。等...
おそらくすでに何人かが答えているように、インターフェイスを使用して、クラス間で特定の動作を強制することができますが、これらの動作は同じ方法で実装されません。したがって、インターフェイスを実装することにより、クラスにインターフェイスの動作があると言っています。 Dog、Cat、Birdなどのクラスは動物の種類であり、おそらく継承する必要があるため、IAnimalインターフェイスは典型的なインターフェイスではありません。代わりに、この場合、IRunnable、IFlyable、ITrainableなどのインターフェイスは動物の行動に似ています。
インターフェースは多くのものに適していますが、重要なことの1つはプラグ可能性です。たとえば、Listパラメーターを持つメソッドを宣言すると、Listインターフェイスを実装するすべてのものを渡すことができるため、開発者は、大量のコードを書き直すことなく、後で別のリストを削除してプラグインできます。
インターフェースを決して使用しない可能性はありますが、プロジェクト、特に何らかのフレームワークをゼロから設計する場合は、おそらくそれらに慣れる必要があります。
Coad、Mayfield、Kernによる Java Design のインターフェイスに関する章を読むことをお勧めします。彼らはそれを平均的な紹介文よりも少し良く説明しています。 Javaを使用しない場合は、この章の冒頭を読むだけでよく、これは主に概念です。
ラーセナルが言ったことを拡大する。インターフェースは、すべての実装クラスが従わなければならない契約です。このため、コントラクトに対するプログラミングと呼ばれる手法を使用できます。これにより、ソフトウェアを実装から独立させることができます。
システムに柔軟性を追加するプログラミング技術と同様に、インターフェイスもある程度の複雑さを追加します。それらはしばしば素晴らしいものであり、どこでも使用できます(すべてのクラスのインターフェースを作成できます)-しかし、そうすることで、より複雑なシステムを作成し、保守が難しくなります。
いつものように、ここにはトレードオフがあります:保守性に対する柔軟性。どちらがより重要ですか?答えはありません-プロジェクトによって異なります。しかし、すべてのソフトウェアを維持する必要があることを忘れないでください...
だから私のアドバイス:本当に必要になるまでインターフェースを使わないでください。 (Visual Studioを使用すると、2秒で既存のクラスからインターフェイスを抽出できます。急がないでください。)
そうは言っても、いつインターフェースを作成する必要がありますか?
突然が2つ以上の同様のクラスを処理する必要があるメソッドをリファクタリングしているときに実行します。次に、インターフェイスを作成し、このインターフェイスを2つ(またはそれ以上)の同様のクラスに割り当て、メソッドのパラメータータイプを変更します(クラスタイプをインターフェイスタイプに置き換えます)。
そしてそれは動作します:o)
1つの例外:オブジェクトをモックするとき、インターフェイスははるかに使いやすいです。そのため、私はしばしばこのためのインターフェースを作成します。
PS:私が「インターフェース」と書くとき、私は意味する:純粋なインターフェースクラスを含む「任意の基本クラスのインターフェース」。抽象クラスは、ロジックを追加できるため、多くの場合、純粋なインターフェースよりも優れていることに注意してください。
よろしく、シルバン。
library developer(他のコーダー用にコーディングする人)になると、インターフェイスが明らかになります。私たちのほとんどは、既存のAPIとプログラミングライブラリを使用するapplication developerで始まります。
インターフェイスは契約です と同じ行に沿って、インターフェイスがコードの一部を作成する優れた方法であることはまだ誰も言及していませんstable。 teamプロジェクトの場合(または、他の開発者が使用するコードを開発している場合)、特に役立ちます。そこで、具体的なシナリオを以下に示します。
teamでコードを開発している場合、他の人が書いたコードを使用している可能性があります。彼らはあなたの(安定した)インターフェースにコーディングするときに最も満足し、あなたはあなたのチームのコードを壊すことなく実装を変更する自由がある(インターフェースの背後に隠されている)ときに満足します。 information hidingのバリアントです(インターフェイスは公開されており、実装はクライアントプログラマから隠されています)。 保護されたバリエーション の詳細をご覧ください。
こちらもご覧ください インターフェースへのコーディングに関する関連質問 。
インターフェイスを使用する目的は非常に多くあります。
多態的な動作で使用します。子クラスへの参照を持つインターフェイスを使用して、子クラスの特定のメソッドを呼び出す場所。
最も一般的な使用法がCOMオブジェクトであるように、必要なすべてのメソッドを実装するためのクラスとの契約を持つこと。ラッパークラスは、インターフェイスを継承するDLL;これらのメソッド舞台裏で呼び出され、それらを実装する必要がありますが、COM DLLで定義されているのと同じ構造を持ち、それらは公開するインターフェイスを通じてのみ知ることができます。
クラス内の特定のメソッドをロードしてメモリ使用量を削減します。 3つのビジネスオブジェクトがあり、それらが単一のクラスに実装されている場合のように、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();