こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

「インターフェイス」って何の為に必要なんですか?

“値を変更できるフィールドがもてない”・“抽象クラスしかもてない”のに何の為に記述するんだろう?と思って、インターフェイスを入力せずに実行してみたのですが、入力してもしなくても同じ結果が出ました。 同じ結果が出るならなぜ必要なんですか?

************* コード ****************************************
//のりものインターフェイス
interface iVehicle{
void vShow();
}
//材料インターフェイス
interface iMaterial{
void mShow();
}
//車クラス
class Car implements iVehicle,iMaterial{
private int num;
private double gas;

public Car(int n, double g){
num = n;
gas = g;
System.out.println("ナンバー"+ num + "ガソリン量"
+gas + "の車を作成しました。");
}
public void vShow(){
System.out.println("車のナンバーは" + num +"です。");
System.out.println("ガソリン量は" + gas + "です。");
}
public void mShow(){
System.out.println("車の材質は鉄です。");
}
}
class Sample1{
public static void main(String[] args){
Car car1 = new Car(1234, 20.5);
car1.vShow();
car1.mShow();
}
}
**************************************************************
<実行結果>
「ナンバー1234ガソリン量20.5の車を作成しました。
 車のナンバーは1234です。
 ガソリン量は20.5です。
 車の材質は鉄です。              」
インターフェイスを記述してもしなくても、同じく上記の結果が
出ました。

※ちなみに抽象クラスもいったい何なのかよく分りません。

投稿日時 - 2008-03-17 03:05:40

QNo.3869621

困ってます

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

説明合戦に参戦します。
インターフェースは「ルール」です。
実世界で言うと、「単三型乾電池」のことです。単三型乾電池は、円柱状の形をしており、プラスが盛り上がっていて、マイナス方向からは電子が放出されるという決まりがあります。
電子機器は、「単三型乾電池」の形が合うように作られているので、単三型乾電池を使うことが出来ます。つまり、円柱状の凹みがあり、マイナス方向から電子を受け取るように出来ています。

しかし、「単三型乾電池」は単なるルールなので、この世の中には「単三型乾電池」は存在しません。あるのは「アルカリ単三型乾電池」や「ニッカド単三型乾電池」です。

「アルカリ単三型乾電池」や「ニッカド単三型乾電池」は「単三型乾電池」をimplementsしているクラスです。

さて、ここでなぜインターフェースを利用するかというと、電子機器が、「アルカリ単三型乾電池」を利用するように作成したとしましょう。例えば、利用できるアンペア数が固定されているものします。そうすると、「ニッカド単三乾電池」は使えないようになってしまいます。また、今後新しい電池が開発されても、動揺に利用できません。例えば「オキシドライト単三乾電池」も使えません。
こうなると、電子機器の使い勝手が悪くなってしまいます。

なので、電子機器は最低限のルールだけを利用して電池にアクセスするようにします。このルールが「単三型乾電池」です。

どうでしょう?

投稿日時 - 2008-03-18 21:17:41

お礼

すみません!ずっと前に読んでいてお礼を書いたつもりで
いたのに、見直していたらまだ書いてなかったことに気づいて・・・

乾電池という例えがちょっとばかり難しかったですが、
でもよく理解できました。

今更ですが、ありがとうございました。

投稿日時 - 2008-03-27 18:16:05

ANo.8

このQ&Aは役に立ちましたか?

5人が「このQ&Aが役に立った」と投票しています

回答(12)

>同じ結果が出るならなぜ必要なんですか?

基本的にインターフェイスっていうのは、再利用性や抽象度、保守性などを高めるために利用されます。よって、質問者さんのソースでも、現状では、あまりインターフェイスの必要性が感じられないかもしれませんが、そのソースを元に機能拡張していこうとすれば、がらりと変わってきます。

そもそも、『入力してもしなくても同じ結果が出ました。』っていうのも、単にインターフェイスやオーバーライドと同等の処理をカスタムメソッドで実装したまでであって、同じ結果となるような実装をしたんだから当たり前なわけですよ。

※ちなみに抽象クラスもいったい何なのかよく分りません。

クラスも抽象クラスもインターフェイスもオブジェクト指向の世界では、全て同じものです。強いてあげれば、右に行くに連れて抽象度が上がっていきます。

クラス → 抽象クラス → インターフェイス

#1さんのおっしゃられていた「『インターフェイス』の恩恵」について、以下に私なりの表現で説明してみようと思います。

教えて!goo > カテゴリ一覧
http://oshiete.goo.ne.jp/oshiete_list.html

上記のサイトは、ここを利用している方々ならば一度は訪れたことがあると思います。これもまた、オブジェクト指向によって構成されています(その他にも有名なのであれば、本の目次なんかもオブジェクト指向で形成されていますよね)。

具体的には、本来「カテゴリ一覧」というサイトがなくても、ここを利用することは可能ですが、きちんと分類されていれば自分のよく利用しているカテにすぐアクセスできます。ここで、汎用的な「カテゴリ」というのを「インターフェイス」として抜き出し、そこで利用される「属性」や「操作」を事前に仕様として定義しておくわけですよ(各カテゴリー内の内容は違えど、新規に質問したり、回答したり・・といったような機能は、どのカテでも同じですよね)。

質問者さんの言うように、インターフェイスを使わずとも同じ機能を実現することは可能ですが、ただ上記のような階層型の設計にしておけば(厳密にはCompositeパターンと言います)、また新たに「Web3.0」とか、「サードライフ」、「次期WindowsOS」にと、カテゴリの追加が必要になったとしても、非常に効率的に機能拡張ができるというわけなんですよ。

それと同時に、クラス化による分類で、他のクラスへの影響度も小さく品質をより高めることも可能という訳です。

#6さんがおっしゃっていたのは、イベントハンドラ(イベントドリブン、イベントリスナーとも)のことですね。

java.awt.event
インタフェース ActionListener
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/awt/event/ActionListener.html

私と「イベントハンドラ」との出会いは、iアプリを勉強していた時のことですが、上記のサイトなどでも「何てシンプルなんだろう。」と思ったりするものです。(まだ、勉強を始めたばかりの人には、その偉大さがピンとこないかなあ・・。)

最後に、ワンポイントアドバイスです。(これがわかれば、SJC-A合格も間近。)

・クラスは、インターフェイスを実装(implements)することは可能。
・インターフェイスは、クラスを継承(extends)出来ないが、他のインターフェイスによる継承(extends)は可能。
・インターフェイスに他のインターフェイスを実装(implements)することは、不可能。

投稿日時 - 2008-03-25 03:54:29

お礼

初心者の私には難しい言葉が多くて理解できないことも
結構ありましたが、
>具体的には、本来「カテゴリ一覧」というサイトがなくても、ここを利用することは可能ですが、きちんと分類されていれば自分のよく利用しているカテにすぐアクセスできます。ここで、汎用的な「カテゴリ」というのを「インターフェイス」として抜き出し、そこで利用される「属性」や「操作」を事前に仕様として定義しておくわけですよ。

↑ここの説明が例えもよく、分かりやすかったです。

でもすごいですね、専門家のような解説だなと思いました。
自分のこの説明を全部理解出来るような知識をみにつけられる
ようになりたいです。道のりは遠いですが・・・

ありがとうございました。

投稿日時 - 2008-03-27 18:33:41

/**
最近、多相性のコードを作成していたので、ちょっとだけここでも遊んでみた。

以下公式サイトによると正確には5段階に分かれていて、常に「エンジン」と「モーター」の2つが動いているわけではないらしいが、それも実装すると冗長的になるのでここでは割愛。

toyota.jp プリウス > 機能・メカニズム
http://toyota.jp/prius/dynamism/ths2/index.html
*/

import java.util.*;
import static java.lang.System.*;

//のりものインターフェイス
interface iVehicle{
 void vShow();
}

//材料インターフェイス
interface iMaterial{
 void mShow();
}

//燃費クラス
class MileagePrius implements iVehicle{
 public void vShow(){
  System.out.println("リッター35.5km/Lです。");
 }
}

//モータークラス
class Motor implements iMaterial{
 public void mShow(){
  System.out.println("\nモーターを使用中です。\n");
 }
}

//エンジンクラス
class Engine implements iMaterial{
 public void mShow(){
  System.out.println("\nエンジンを使用中です。\n");
 }
}

//ハイブリッド車クラス
class HybridCar{
 private String shashu;

 public HybridCar(String ss){
  this.shashu = ss;
  System.out.println(shashu + "の車を運転します。");

  if(ss.equals("プリウス")){
   MileagePrius mp = new MileagePrius();
   mp.vShow();
  }
 }

 void THSII(int num){ //ハイブリッドシステム
  iMaterial im;

  if(num == 1){
   im = new Motor();
   im.mShow();
  }else if(num == 2){
   im = new Engine();
   im.mShow();
  }else{
   System.out.println("\n半角の1か2を入力してください。\n");
  }
 }

}

//テストクラス
public class Sample1{
 static public void main(String... _$){
  HybridCar Prius = new HybridCar("プリウス");
  Scanner scan = new Scanner(in);

  System.out.println("\n 以下の何れかの数字を入力して、ハイブリッド・シナジー・ドライブの開始。");
  System.out.println("1 → 「モーター」");
  System.out.println("2 → 「エンジン」");

  for(;;) Prius.THSII(scan.nextInt());
 }
}

投稿日時 - 2008-03-25 03:49:18

ANo.10

8番の方の「ルール」というのが、自分の理解と近いです。例えば

public interface Action {
  String doAction(String string, Object object, int i) throws Exception;
}

というインターフェイスをimplementsするクラスは、

String型の引数ひとつとObject型の引数ひとつとint型の引数ひとつを取り
String型の値を返し
Exceptionという例外を発生させる可能性のある
doActionという名前のメソッド

を必ず実装しなければなりません。

言い方を変えると、上のインターフェイスをimplementsしているクラス(正確にいうと具象クラス)は

String型の引数ひとつとObject型の引数ひとつとint型の引数ひとつを取り
String型の値を返し
Exceptionという例外を発生させる可能性のある
doActionという名前のメソッド

を必ず持っている、持っていることが保証されるということです。

なので、上のインターフェイスをimplementsしているクラスならば、世界中の誰が作ったどんな名前のクラスであろうと、インスタンス化してdoActionを呼べるわけです。インターフェイスというルールを適用してくれたクラスは、安心して同じシグニチャのメソッドを呼べるというイメージです。同じシグニチャのメソッドとは、メソッド名、戻り値、引数構成、例外発生可能性定義がまったく同じメソッドという意味です。

これだけの説明で理解できるとは思われませんが、特に思うのは、オブジェクト指向の三つのポイントといわれる

カプセル化
継承
ポリモフィズム(多態性)

の中のポリモフィズムの実現方法がインターフェイスの利用であり、自分としては

インターフェイスの理解 = オブジェクト指向の理解

にかなり近いくらい、インターフェイスの利用方法を理解することは重要だということです。インターフェイスの理解なしには、有名なGoFのデザインパターンなども理解できません。真剣にオブジェクト指向のプログラムを勉強していかれるということならば、2・3年かけてでも完全に理解した方がよいかと思います。また、インターフェイスを自分のものにした方が、プログラミングがより楽しくなるとも思いますし。

投稿日時 - 2008-03-24 23:41:19

ANo.9

> 研修の講師には後回しでいいと言われたし、使い道が少しということは、そこまで実務で使用することはないんですかね?

そうでもないです、結構よく使います。多いときは3割:7割でインターフェイスとクラスがあるようなことも。
後回しでよいのはインターフェイスの本質的な意味とか、使い道のことであって、文法的な宣言方法とか、既存インターフェイスのソースの読み方とかは今からでも理解して下さい。「インターフェイスを活用したプログラムが書ける」ようになるのはずっと先でもいいですが、「インターフェイスを活用したプログラムが読める」のはすぐに必要なスキルです。
あとは、初心者であればインターフェイスよりも、メソッドの引数と戻り値など、先に理解しておくべきこともおおいということですね。

投稿日時 - 2008-03-20 07:16:09

お礼

お礼遅くなってすみませんでした。

そうですね、実際いまだに引数や戻り値をちゃんと理解できて
なくてこんがらがる事があるので、まずは基本的なことの方を
ちゃんと覚えなきゃいけないと思います。
例えば引数や戻り値ではないけど、Stringクラスの中にもたくさんの
メソッドがあって、そういうのを活用して記述するような問題が
多く出てくるので、よく使用するメソッドくらいはちゃんと理解したい
ものです。

色々解説していただき、ありがとうございました。

投稿日時 - 2008-03-27 18:23:46

ANo.7

この質問、面白いので、私の私見を書きます。
オブジェクト指向言語
 共通のデータ(プロパティ、その昔は共通変数とか呼ばれれたもの)と実行内容あるは実行する単位(メソッド、その昔は関数とか、サブルーチンと呼ばれた物)をまとめたもの(クラス)をプログラムの単位
とする言語
インタフェース
 御質問者の例で、車が材料で乗り物なら、いっぱいクラスを作って
携帯の材料とか、パソコンの材料とか、そしたら材料だけの操作したいし!乗り物なら、バスとか電車とか飛行機とか、乗り物だけの操作したいし!と思うと使い道が少しあるかな!
 私の知る限り、Javaの元になったC++ではインタフェースはなかった
気がします。

投稿日時 - 2008-03-18 18:33:27

お礼

回答ありがとうございました。

>オブジェクト指向言語

プログラムの単位ですか・・・
ごめんなさい、やっぱりよく分らないです。
もうちょっと言語の意味が分ってきたら理解できるかも。

>インタフェース
車が材料で乗り物なら、いっぱいクラスを作って
携帯の材料とか、パソコンの材料とか、そしたら材料だけの操作したいし!乗り物なら、バスとか電車とか飛行機とか、乗り物だけの操作したいし!と思うと使い道が少しあるかな!

なんとなくおっしゃりたい事の意味はわかります。
研修の講師には後回しでいいと言われたし、使い道が少しということは、そこまで実務で使用することはないんですかね?

投稿日時 - 2008-03-20 06:07:35

ANo.6

趣味プログラマの勝手な意見を少し述べてみます。
CUI で一回実行して出力しておしまいなら、インターフェースなどほとんど必要ないでしょう。
でも、appletなど、GUIで、ボタンクリックやキー入力、マウスの動作をトラップするためには、Listnerといわれるインターフェース群を使いこなさなければ、まともなGUIプログラムは出来ません。
CUIでも、標準入力というのがあるけど、GUI入力の複雑さの比ではないので。
オブジェクトの理解も、GUIプログラムの方が、ボタンやパネルを自分で作ることで、よりヴィジュアルに理解できると思う。
抽象クラスも、似たようなパネルを沢山作ってすげ替えをするときにその有用性を実感する(これは自己経験、できあがった喜びは格別\(^o^)/)。
私の勝手な結論:オブジェクト指向(特に、インターフェース、抽象クラス)は、GUIプログラミングをものすごく楽にするために存在する。
Javaに限らず、この概念なしに、今ほど使いやすいGUIプログラミングはありえなかった、と、私は思っています。

投稿日時 - 2008-03-17 19:18:46

ANo.5

インターフェイスがなくて困ったことがないのですから、価値がわからないのも仕方ないでしょう。
インターフェイスの本質的な意味や活用の仕方の説明があっても、その説明自体が意味不明に思えるので、ますますわからないでしょう。
これらは仕方ないと思います。
まずは、教科書どおり理解して、そういうものなんだと思って下さい。
私は実務プログラミングでいろんな経験をし、苦労をし、なぜ自分はいつも同じような無駄なプログラミングばかり書いているのだろうと考えていたら、あるとき「あッそうか、ここでインターフェイスをつかえばいいんだ、そうすればうまくいく」と気付くようになりました。
※それでも結局うまくいかないほうが多いですが・・・

投稿日時 - 2008-03-17 17:13:15

お礼

ありがとうございました。
そうなんですよね。IT用語辞典などでインターフェイスの意味を調べても、その説明の意味自体理解出来ないんです。
他にも“BufferedReaderクラス”・“Stringクラス”・“Integerクラス”など最初は意味も分らず入力してたものが、その説明が出てきてから「何故ここでこ~なるんだ?」って考えだすとどんどん深みにはまって分らなくなるんです。
全て意味を理解しながら作成しようとしてたら全然勉強が進まなくなってしまうので、もうそういうものなんだと思ってやっていくしかないですかね?

しかも、研修のとき講師に聞いたら、「インターフェイスは後回しでいいんで飛ばして進めて下さい」と言われました。
そ~いうことは先に言ってくれ!

投稿日時 - 2008-03-20 05:54:17

ANo.4

ANo.2のお礼から
> ◆よく「オブジェクト指向」という言葉を聞きますが、どういう意味
>  なんですか?

それまでの機能(関数)中心の考え方からデータ構造(クラス)中心の考え方に移したプログラミングの方法です。オブジェクト指向をちゃんと説明しようとすると本一冊くらいは書けてしまいますので、本を読んで勉強してください。
# Javaの本じゃないけど
# 『オブジェクト指向入門 第2版 原則・コンセプト』
# を勧めときます

> ◆+ iVehicle vehicle1 = car1;
>  + iMaterial material1 = car1;
>   ↑この部分、+をつける理由って・・・(?)
ああ、これは引用に対する追加行という程度の意味です。
同様に<で始めている行は前の行を置き換えるつもりです。

投稿日時 - 2008-03-17 15:08:45

お礼

ありがとうございます。

今は参考書を早く終わらせることで手いっぱいですが、その後で
薦めて下さった本読んでみたいと思います。

投稿日時 - 2008-03-20 05:42:58

ANo.3

ここのコミュニティでは、過去何度も同じような質問がされています。

中にはよい質問と回答もあるので、Javaカテゴリ(本カテゴリです)にて「インターフェイス」等の言葉で検索してみて下さい。

http://oshiete.goo.ne.jp/search/search.php?status=select&PT=&from=&nsMT=&mt_opt=a&qatype=qa&c=253&ct0=205&ct1=221&ct2=253&st=all&tf=all&MT=%A5%A4%A5%F3%A5%BF%A1%BC%A5%D5%A5%A7%A5%A4%A5%B9+interface&ct_select=1&c=253

投稿日時 - 2008-03-17 14:43:48

ANo.2

質問のコードはインタフェースを理解するためには無意味です。
> class Sample1{
> public static void main(String[] args){
> Car car1 = new Car(1234, 20.5);
+ iVehicle vehicle1 = car1;
+ iMaterial material1 = car1;
> car1.vShow();
< vehicle1.vShow();
> car1.mShow();
< material1.mShow();
> }
> }
このように少なくともインタフェース型の変数を使わないと。
実際に使う場合はインタフェースを継承するクラスも複数あるのが普通です。

インタフェースはJavaにおいて多重継承を実現するための手段です。
多重継承はオブジェクト指向で重要な概念ですが、プログラミング言語処理系での実装には難しい部分があり、また使いこなすのにも難しい部分があります。
このためJavaでは一般的なクラスによる多重継承はなくし、インタフェースにより多重継承の一部機能だけを実現しています。

投稿日時 - 2008-03-17 11:56:38

お礼

ありかとうございます。
でも初心者の私には難しい言葉ばかり・・・
言葉の意味を調べながら読み直してみます。

ただ出来れば2つ程教えていただけないでしょうか?
◆よく「オブジェクト指向」という言葉を聞きますが、どういう意味
 なんですか?
◆+ iVehicle vehicle1 = car1;
 + iMaterial material1 = car1;
  ↑この部分、+をつける理由って・・・(?)

投稿日時 - 2008-03-17 13:19:43

ANo.1

さて、このインターフェースですが私はネット上や参考書でまともな説明を見たことがありません。大半は著者が理解していないことが多いです。よってインターフェースが理解できないのは当たり前なので心配いりません。
私はまずなぜジェームズゴスリングがこのような仕組みを取り入れたかを考えました。そもそもオブジェクト指向とは何か。深く考えました。するとこのオブジェクト指向に隠された社会的陰謀が見えてきます。
Javaに限らずあなたもこの「インターフェイス」の恩恵を受けています。色々なところで受けています。どこで受けているか考えてみましょう。見つかった瞬間すべてを理解できます。
あなたはとてつもない喜びを感じるでしょう。
その喜びをJavaに実装したジェームズの気持ちを共有することになるでしょう。

投稿日時 - 2008-03-17 04:19:50

あなたにオススメの質問