• ベストアンサー

なぜインタフェースを使うのか?

カテゴリはJavaですが、オブジェクト指向という観点での質問です。 私はオブジェクト指向を勉強中です。(C#) そこで、疑問に思ったのがタイトルで示したインタフェースについてです。 以下に疑問を列挙します。 1.インタフェースはなぜ使うのですか? 2.使うメリットはなんですか? 3.インタフェースのインスタンスって作れるのですか? 4.インタフェースは必ずどこかのクラスに継承されないといけないのですか?  単体では何もできないのですか? 5.具体的な使い方を教えてください。 全部でなくてもよいのでわかる方ご教授よろしくお願いいたします。

  • Java
  • 回答数8
  • ありがとう数8

質問者が選んだベストアンサー

  • ベストアンサー
  • dekopa-
  • ベストアンサー率42% (161/378)
回答No.5

インターフェースとは「役割」です。 一般的なインターフェースの命名規則は「~ableを末尾に付ける」とあります。例えば「比較できる」なら「ICompareble」です。 メディア再生ならplay,stop等を持ったIPlayableインターフェースが考えられます。これで動画、音楽、静止画が文字通り「再生できます」。 クラスは実装とインターフェースの両方を継承しますが、これでは不便なことが沢山あります。最も不便なのは、余計なメソッドが沢山付いてくること、多重継承でもしない限り、継承だけでは機能を共有しきれない(多重継承は多重継承で、別の問題がある)事です。 インターフェースにはこの制約がありません。「~ができる」という役割に必要なメソッド群を定義し、その役割を持たせたい複数のクラスに実装させれば良いのです。 また逆に、1つのクラスに複数の役割を持たせることができます。 インターフェースは、引数の型指定に使うと用途がよく分かります。 元のインスタンスが何を継承していようと、インターフェースを通じて操作できるのはそのインターフェースに定義されたメソッドだけ、つまり純粋に「ある役割について操作したい」というメソッドを定義できます。 1.インタフェースはなぜ使うのですか?  継承では制約が多い場面で、特定の「役割」に基づいた操作を定義したいとき、インターフェースを使います。 2.使うメリットはなんですか?  継承より制約が少ないことです。中身が空っぽというデメリットは、「委譲」で回避できます。委譲とは、実装済みのクラスに処理を委ねてしまう(単なるクラス呼出し)です。 3.インタフェースのインスタンスって作れるのですか?  作れませんが、インターフェースの引数や変数に、インターフェースを実装したクラスのインスタンスを代入できます。この辺の使い勝手は普通のクラスと同じです。 4.インタフェースは必ずどこかのクラスに継承されないといけないのですか?  単体では何もできないのですか?  中身がありませんし、それだけではインスタンス化できませんから、YESです。 5.具体的な使い方を教えてください。  理論的な話なら「Javaオブジェクト設計」というペーター・コード氏の著作をお薦めします。  C#での具体例なら、参考URLにプラグインの作り方が載っています。

参考URL:
http://dobon.net/vb/dotnet/programing/plugin.html

その他の回答 (7)

  • bobviv
  • ベストアンサー率50% (13/26)
回答No.8

 インターフェースの威力を知りたければ、たとえばストラテジ(Strategy)パターンと呼ばれているデザインパターンのサンプルコードなど一度ごらんになるとよいと思います。  細かいこと言うと、インターフェースが実現するポリモーフィズム(多態性)は、コンパイル時にはインターフェースSの型として型チェックされたオブジェクトが、実行時にはSを実装したクラスのインスタンスなら何でもよいという「ズレ」によって支えられています。インタフェースの効能はというと、  1.多態性(すでにご指摘の)  2.コントラクトが守られているかどうかをコンパイラによってチェックさせることができる。  3.単一のオブジェクトに対して、今問題にしたいひとまとまりの機能一覧を抽象して顕在化させることができる。この時特に「他のインタフェースや実装の詳細は”見えないし、見なくて済む”」 といった諸点にあると思います。  いずれにしろ、JavaやC#をお書きになるならインターフェースを理解しないっていう手はありません。その威力に触れたら、今とは逆にインターフェース中毒になってしまうくらい使いたくってしょうがなくなると思いますよ^^。

  • unibon
  • ベストアンサー率47% (160/340)
回答No.7

いろいろな考え方はありますが、私はつぎのような考え方をお勧めします。 要は、呼ばれることだけに特化した「インターフェース」の定義です。その使用方法を超えるものは class (abstract class も含む)にしたほうが良いです。 ただ、interface は「軽い」ので、コーディングの都合上、本来は class のほうがふさわしいのだけど、便宜上 interface にしてしまう、ということも多いです。 巷の書籍等の解説では interface を過度に使いがちな傾向があると思います。しかし、設計の開始時点では、まずは interface よりは abstract class を使うことを検討されたほうが良いです。その中から interface で済むものを、interface に「降格」させるような感じにすると良いでしょう。 > 1.インタフェースはなぜ使うのですか? クラスが呼ばれる際の呼ばれ方、および呼び側での呼び方、を定義するためです。 > 2.使うメリットはなんですか? 古いものにたとえると、C の関数ポインタのプロトタイプ宣言に、近いものになります。 interface がないと、コンパイル時にメソッドを呼ぶ時の引数の並びや引数の型が分からないままになってしまいます。実行時にこれらを解決する方法も考えられなくはないのですが、概して面倒になります。 > 3.インタフェースのインスタンスって作れるのですか? 呼ばれ方の定義だけですので、それだけではインスタンスは作れません。まあ、しいて言えば、 class FooClass extends Object implements BarInterface みたいなことをすれば良いわけですが。 > 4.インタフェースは必ずどこかのクラスに継承されないといけないのですか? >  単体では何もできないのですか? 呼ばれ方の定義なので、単体で使うということはないです。interface を使うからには呼ばれるクラスがあるはずなので、そのクラスが interface を implements します。 > 5.具体的な使い方を教えてください。 リスナ(listener)が interface の最たる使い方になります。 Button の ActionListener などです。

mkmarimo
質問者

お礼

ご回答ありがとうございます。 unibonさんだけでなく、他の方々にもこの場でお礼を言わせていただきます。 みなさんのお陰で、インタフェースの用途とか使う目的は分かってきました。 ありがとうございました。

  • ency
  • ベストアンサー率39% (93/238)
回答No.6

他の方々の回答で、ほぼ出尽くしているとは思いますが。。。 > 1.インタフェースはなぜ使うのですか? > 2.使うメリットはなんですか? クラスの継承をいわゆる「is-a関係」のみに限定するためです。 決して「(クラスの)多重継承の代用品」ではありません。 (クラスの)多重継承に相当することをやろうとした場合、インタフェースによって同等のことができるためこのような言われ方をすることもありますが、本来の意味はもう少し違うところにあると思います。 > 3.インタフェースのインスタンスって作れるのですか? 作れません。 > 4.インタフェースは必ずどこかのクラスに継承されないといけないのですか? >  単体では何もできないのですか? インスタンスが作れないため、インタフェース単体では何もできません。 ちなみに、インタフェースは継承ではなく「実装 (implement)」という言葉を使いますね。 > 5.具体的な使い方を教えてください。 インタフェースを文字通りとらえれば良いのではないでしょうか。 たとえば、円を「描く」、三角形を「描く」、…といったように図形を「描く」という共通の「インタフェース」を用意する場合とか。 もちろん、図形というクラスに「描く」というメソッドを用意しておいて、それを継承するという方法も考えられます。 ここでよく考えてみてください。 「図形」というクラスの意味は何でしょうか。 ただ単に「描く」という操作のみのために、クラスを作る意味は本当にあるのでしょうか。 円を「描く」場合には、「中心座標から半径の距離にある点を結んでいく」という方法を取るのに対して、三角形を「描く」場合には、「三点の座標を順番に結んでいく」という方法を取りますよね。 つまり、「描く」という処理の「実装」方法が異なるわけです。 まさに「異なる処理を同じインタフェースで実装する」ことこそが、インタフェースの本来の姿なのです。 もちろん、他の要素を考えたときに「図形」というクラスが必要だということになるかもしれません。 そうするメリットが大きいのであれば、それでも良いと思います。 インタフェースは、「何でもかんでもクラスを作って継承させれば良い」といういい加減な設計をさせないための指標の一つであると言っても良いかもしれません。 インタフェースについては「Java には多重継承がないから、その代用品としてインタフェースが存在する」というような、いかにも Java の欠陥 (?) を補うものであるような言われ方をすることもあるようです。 しかし、わざわざクラスを新たにクラスを作らなくてもインタフェースで十分間に合うことも多いはずです。 いずれにしろ、設計段階でこのあたりの話を整理できていなければ、まともなプログラムにはならないと思います。 こんな感じで、いかがでしょうか。

  • UKY
  • ベストアンサー率50% (604/1207)
回答No.4

他の回答者より本質的な話をしてみたいと思います。 C# や Java は「静的な型付け」を行う言語です。「型」というのは、あるオブジェクトがどのようなメソッドやフィールドを持っているか、ということです。そして、静的な型付けというのは、コンパイルの時にプログラム内のオブジェクトの型が正しいかどうかを (ほとんど) 全てチェックすることを言います。 逆に、JavaScript はオブジェクト指向言語ではあっても「動的な型付け」を行います。動的な型付けを行う言語では、オブジェクトの型が正しいかどうかはプログラムが実際に実行されるときにチェックされます。動的な型付けを行う言語には、インタフェースという言語機能は普通は存在しません。 さて、C# は静的な型付けの言語だといいました。そこで、コンパイル時の型のチェックがどのように行われるか簡単な例をあげてみましょう。文字列から Substring メソッドで一部を取り出します。 string s = "abc 123 xyz"; string t = s.Substring(4, 3); ここで、変数 s に対して問題なく Substring メソッドが使えるのはなぜかを考えてみると、コンパイラはここで次のような三段論法を使っています。 1. 変数 s の型は string クラスである。 2. string クラスには Substring メソッドが定義されている。 3. よって、変数 s に対して Substring メソッドを呼び出すことが出来る。 したがって、コードを次のように書き換えるとコンパイルできなくなります。 object s = "abc 123 xyz"; object t = s.Substring(4, 3); なぜなら、「object クラスには Substring メソッドが定義されている」が成り立たないからです。 ここで、三段論法の一つ目の命題に注目してみます。 「変数 s の型は object クラスである。」 ここでは、オブジェクトの型は object というクラスによって規定されているので、object クラスで定義されているメソッド (ToString など) を変数 s に対して使うことはできます。しかし逆に言えば、object クラスで定義されていないメソッドは使えません。 上の例では、変数 s の実体は string オブジェクトであるにもかかわらず、object クラスという型に阻まれて、Substring メソッドを使えないわけです。 というわけで、静的な型付けの言語では、オブジェクトのメソッドやフィールドを使うためにはそのオブジェクトの型がとても重要なのです。 さて、上のコードでは string オブジェクトを object 型の変数に代入しました。つまり、子クラスのオブジェクトは親クラスの型の変数に代入することができます。 では あるクラスのオブジェクトをその「いとこクラス」の型の変数に代入できるでしょうか。残念ながらできません。子クラスのオブジェクトは親クラスのオブジェクトの振りをすることができますが、いとこ同士だとそうとは限らないからです。 では、遠い親戚 (または、赤の他人) 同士が同じメソッドを持っているときに、たとえクラスに親子関係がなくても 同じ型として扱うにはどうすればいいのでしょうか。 親子関係という制約があるのは、クラスによって型が決められているからです。そこで、クラスとは異なるものによって型を決めるようにすれば問題を解決できます。それがインタフェースです。 例えば、string クラスには CompareTo というメソッドがあって、二つの string オブジェクトを比較できます。また、int 構造体にも CompareTo というメソッドがあって、二つの int 値を比較できます。string クラスと int 構造体には親子関係はないので、そのままでは string のオブジェクトと int の値を同じ型で扱うことはできません。 しかし、どちらも CompareTo メソッドが使えるという点では共通しています。そこで、IComparable というインタフェースを作り、string クラスと int 構造体はそれぞれ IComparable インタフェースを実装するようにします。IComparable インタフェースには、「CompareTo メソッドがある」ということだけが書かれています。 こうすることで、クラスに親子関係がなくても、それぞれのオブジェクトを IComparable という一つの型で同じように扱うことができるようになります。

参考URL:
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1570935
  • thamansa
  • ベストアンサー率40% (95/232)
回答No.3

インタフェースは、クラス間の依存性を低めることができます。 言い換えると、インタフェースを使うと、実装クラスがなくてもインタフェースを使うクラスを作ることができます。 例 AaaクラスがBbbクラスを使うプログラムを作るとします。AaaクラスがBbbクラスを使うとは、たとえば   void foo(Bbb b)というメソッドがAaaクラスにあるということです。 また、Bbbクラスには   void bar(int i) 見たいなメソッドがあって、foo() から bar() を呼び出すことになるとします。 このとき、Bbbがクラスである場合、Aaaのソースコードをコンパイルするには、Bbbクラスのコンパイルが終わっていなければなりません。 Bbbクラスが複雑で、開発に時間がかかる場合はダミーのBbbクラスを作らなければなりません。 では、Bbbをインタフェースにしたらどうでしょう。 Bbbは void bar(int i)の宣言だけでいいのですぐ作れます。 Aaaは、Bbbインタフェースがあるのでコンパイルもできます。テスト用には Bbbを実装した BbbStab スタブクラスでも作ればいいでしょう。 ダミークラスではないので、本物の実装クラスができたときに上書きする必要もありません。

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.2

もともとオブジェクトの継承には2つの側面があります。 その一つがインターフェースの継承であり、もう一つが実装の継承です。 classはこの継承の両方を実現しますが、interfaceはインターフェースの継承のみを実現します。 interfaceを使うのは多重継承の実現のためです。実装の継承を含めた多重継承の実現は言語仕様としてもコンパイラの実装としても複雑になり難しいため、これを避けるために多重継承はインターフェイスの継承のみとし、そのためにclassとは別にinterfaceを用意しています。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

C#の話(javaも概ね同じ)で(おおざっぱな話なので話半分で) 1.インタフェースはなぜ使うのですか? 2.使うメリットはなんですか? ・多態性を実現する ・抽象クラスを書くより記述が楽できる ・抽象クラスと違って多重実装、多重継承ができる 3.インタフェースのインスタンスって作れるのですか? インターフェースのインスタンスは作成できないが、 インターフェースをデータ型とする変数などを宣言することはできる。 (インターフェースを実装したインスタンスを代入でき同じメソッドを使用できる(多態)) 4.単体では何もできないのですか? 抽象メソッド(インターフェースとしてのメソッド)しか持たないので 実装されないでは、インスタンスも作れないし、何も(?)できない 5.具体的な使い方を教えてください。 面倒くさいので、 ここのサイトからインターフェースを使っているもの(java)を紹介 http://okwave.jp/kotaeru.php3?qid=1250952

関連するQ&A

  • インターフェイス、列挙型について

    インターフェイスにclone()メソッドが無くて気づいたのですが、 インターフェイスはObjectを継承しないのですか? しかしそれ以外のメソッドは定義されていたので、何らかのクラスを継承しているのでしょうか? 列挙型のメンバにもclone() は無かったですけど、別のメソッドは持っていました。 列挙型や、そのメンバもスーパークラスを持っているのですか?

  • ADODB.Connectionはインターフェイス

    いつもお世話になっております。 C#で特定のDBに接続するクラスを作ろうとADODB.Connection(ADO.Conn)を継承しようとしたところADO.Connはインターフェイスであるため、各メンバの実装をしなくてはなりません。ADO.Connはオブジェクトととしてインスタンスを生成できていたため、なぜインターフェイスがインスタンスを生成してオブジェクトとして使えるのかがわかりません(Excel.Applicationなども同様です)。 これはどのような仕組みになっているのでしょうか?

  • インターフェイスと抽象クラスについて

    オブジェクト指向について学んでいます。 下記のように、単体でクラスを定義して各メソッドの実行する方法などは理解しているつもりです。 class Test { public function __construct() { // コンストラクタ } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } $test = new Test(); $test->setName('太郎'); echo $test->getName(); // 太郎 ここまではいいのですが、インターフェイスと抽象クラスってどんな時に使うべきなのでしょうか? 簡単な例で使い方を紹介しているサイトはいくつかあるのですが実用性がないものばかりで、これらは本当に必要なものなのか?という疑問があります。。。 具体的に実用性がある例で使い方とメリットをおしえていただけませんでしょうか?

    • ベストアンサー
    • PHP
  • インターフェースってズバリ何なんでしょうか?

    最近DirectX9をやってます。 始める→挫折→C++をもう一度勉強→また始める という状況で、だいたいのことは分かってきたのですが、 IDirect3D9というのがいまいち分かりません。 インターフェースというのは私の中では、「関数をたくさん定義して、継承させるためのもの」という適当な認識をしているのですが、 IDirect3D9インターフェースは、インスタンス化されていますし、これを継承したクラスは使いませんし、普通にメンバ関数を扱っています。 いったい、インターフェースとは何なのでしょうか? また、IDirect3D9インターフェースは、何故インターフェース何でしょうか? 是非ご教授ください。

  • マルチプルインスタンスのメリット

    100%の自信をもって回答できる方のみ回答をお願いします。 Java等のオブジェクト指向プログラミング技術において、クラスからインスタンスを たくさん作れるというのが特徴の一つとなっていますが、クラスからインスタンスを たくさんつくれるメリットはなんでしょうか。 クラスからインスタンスをたくさん作れなくても、1つ作れば動くプログラムはたくさんありますし、 そういうプログラムであれば、staticなアクセスにすればよいですよね。 クラスからインスタンスがつくれることを説明した本やサイトは山ほどありますが、 インスタンスがたくさん作れることのメリットを説明した本をみたことがなく、 「なぜオブジェクト指向でつくるのか」という本を買って読みましたが、 納得がいくメリットを感じられませんでした。 また世の中のソースをみると、みんな、すぐにクラスを作ってオブジェクトを作っていますが、 みなさんがどうして、オブジェクトを作らなくてもコーディングできるケースのプログラムを オブジェクトを作るのか不思議でしかたありません。 どうしてオブジェクトを作らなくてもいいケースでもオブジェクトを作るのか、 またたくさんオブジェクトを作れるメリットはなんなのか、教えてください。

  • Javaのインターフェイスの意味

    以前あった質問の回答やネット上での説明を見たのですが、よくわからなかったので質問します。 public interface CharSequence { int length(); } class MyClassWithCharSequenceIF implements CharSequence { public int length() { return 0; } } インターフェイスには、よく多重継承を可能にするメリットがあるという説明がありますが、 public interface CharSequence { int length(); } こんな短い処理を継承する意味があるのでしょうか?クラス内で実装するためにまた public int length() { return 0; } を書かなければならないのは時間・手間のメリットは何もないように思えます。というよりむしろ単なる二度手間ではないでしょうか? クラスの継承は長い記述などを一まとめにして呼び出せるメリットがありますが、インターフェイスの継承にはそれがありません。 いったい何の意味があるんでしょうか?

    • ベストアンサー
    • Java
  • VBがオブジェクト指向言語でない理由

    一般的にVBはオブジェクト指向ではない(VB7でその方向へ向かう)といわれていますが、実際にVBをさわり始め、いろんな本を読んでみると、 1)クラスが作成でき、構造体と関数を1つにまとめ、メンバ(プロパティ・メソッド)を定義付けできる 2)Implementsステートメントでクラスの継承が出来る と、ある程度のオブジェクト指向言語の要件を備えているように見えます。 といっても私はJAVAもSmallTalkも知らないので、「何が真のオブジェクト指向か」というのを良く判っていないのかも知れないのですが。 しかしC++関連書などを読んでいると出てくるクラスの使用例などはVBのそれと大差なく、なぜクラスの作成もできて、継承も可能なVBがオブジェクト指向ではないのか? という疑問がわいてきました。 JAVAとは何が違うのか? これが出来ないからオブジェクト指向ではないのだ! という理由をご存じの方、回答もらえればうれしいです。

  • 継承・実装の関係で悩んでいます。

    継承・実装の関係について悩んでいます。 ここでは、アクセス制御を考えずに、インスタンスかstaticかabstract(ここではabstract final staticやabstract classのこと)の違いで、どう継承するのか考えています。 // 継承 はメソッドのオーバーライドのことを考えます。(オーバーロードは考えない) クラスAからクラスBでオーバーライドしたメソッドは、 クラスCでさらにオーバーライドできるのでしょうか? クラスCが クラスBのクラスAからオーバーライドしたメソッド をクラスBのメソッドとして見たときに、オーバーライドすることは可能なのでしょうか? クラスA │ インスタンスフィールドA │ staticフィールドA │ │ クラスA() { } │ │ インスタンスメソッドA () { } │ staticメソッドB() { } ↓ クラスB extends クラスA │ インスタンスフィールドA // 継承 │ インスタンスフィールドB │ staticフィールドB │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ インスタンスメソッドA () { } // 継承 │ │ インスタンスメソッドB () { } │ staticメソッドB () { } ↓ クラスC extends クラスB implements インタフェースD, ... ↑ インスタンスフィールドA // クラスBのフィールドを継承 │ インスタンスフィールドB // クラスBのフィールドを継承 │ インスタンスフィールドC │ staticフィールドC │ │ サブクラス2() { } │ │ インスタンスメソッドA () { } // クラスBのメソッドを継承 │ インスタンスメソッドB () { } // クラスBのメソッドを継承 │ インスタンスメソッドD () { } // インタフェースDのメソッドを実装 │ インスタンスメソッドE () { } // インタフェースDのメソッドを実装 │ │ │ インスタンスメソッドC () { } │ staticメソッドC() { } │ interface インタフェースD extends インタフェースE ↑ │ staticフィールドD // public static final │ │ インスタンスメソッドD() { } // public abstract │ インスタンスメソッドE() { } // 継承 │ interface インタフェースE staticフィールドE // public static final インスタンスメソッドE() { } // public abstract

    • ベストアンサー
    • Java
  • クラス?オブジェクト?インスタンス?何がなんだか・

    一般的なオブジェクト指向の 定義として下記で合っているのでしょうか お願いします クラス:第2実体(人間) インスタンス:第1実体(例:山田) オブジェクト:色々なインスタンスをさして、抽象的に総称としてオブジェクト 例えば・・クラス:人間、インスタンス:山田 クラス:犬、インスタンス:ゴン 違うクラスのインスタンスをまとめて呼ぶ際にオブジェクト? よく分からなくなっています、よろしくお願いします

  • オブジェクト指向の利点と欠点

    オブジェクト指向についてある程度勉強しました。そしてだいたいのプログラムの組み方は分かってきました。しかし、まだまだはじめたばかりなので実際のところ利点と欠点がわかりません。オブジェクト指向の原理はだいたいわかりますが、多分経験が不足している状態です。カプセル化や継承、多様性...を使うことで度のようなメリット、デメリットがあるのか具体的に教えてください。