質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

5回答

39652閲覧

継承と実装の違い インターフェースについて

kisaragizinzin7

総合スコア90

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

5グッド

10クリップ

投稿2017/03/23 07:28

extends継承とimplements実装の違いについて質問です

コード public class Player{ int winCount; Random rnd = new Random(); public int getPoint(){ int ran = rnd.nextInt(3); //0~2ランダム return ran; } public void addWinCount(){ winCount++; } }
コード public class Player1 extends Player{ @Override public int getPoint(){ int ran = 0; return ran; } }

継承の場合
上のようなPlayerクラスを継承したPlayer1クラスはgetPointメソッドは上書きされるがaddWinCountメソッドはPlayerクラスと同じように使える

実装の場合
下のようなTacticsクラスを実装したRandomTacticsクラスはreadTacticsメソッドが上書き?されている

私の解釈が間違っているからかもしれませんが、どちらも上書きするだけでそんなに大差が内容に感じます。
継承はPlayerクラスがベースにあって継承することで上書きや処理を追加できるのはわかります。
実装の方はただ上書きするだけのように思います。

いまいちよくわからないのでimplementsの使うべきタイミングやメリットを教えていただきたいです。
まとまりのない文章ですがよろしくお願いします。

コード public interface Tactics{ public int readTactics(); }
コード public class RandomTactics implements Tactics{ int winCount; Random rnd = new Random(); @Override public int readTactics(){ int ran = rnd.nextInt(3); //0~2ランダム return ran; } public void addWinCount(){ winCount++; } }
SuibotuKing, Level192, Rino-T_C, tokotaku, aaachi👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

Javaの初心者向けの書籍やサイトでは、インターフェイスの本質的な意味がきちんと説明されていないものが多いですね。まずはインターフェイスの実装とクラスの継承は本質的に異なるということをしっかりと理解しておく必要があります。

英語のinterfaceには「接点」や「仲立ち」、「橋渡し」という意味があります。つまり、インターフェイスというのは、あるオブジェクトと別のオブジェクトの「接点」となる要素ということです。
ここで言う「接点」とは、あるオブジェクトがどのように別のオブジェクトを利用することができるのか?という「仕様」や「規約」と考えることができます。また、「インターフェイスとは契約(contract)である」と言われることもあり、あるクラスが別のクラスに仕事を依頼する際の「決まり事」を定義するためのものであると考えることもできます。

したがって、インターフェイスは、クラスのような「具体的な実装」を提供するものではなく、あくまでも「仕様」や「規約」、「契約」としての役割を提供するためのものだということを理解しておきましょう。

そして、この「規約」や「仕様」、「契約」というのは具体的には、インターフェイスの「型」と「メソッド」によって明示されることになります。

インターフェイスの「型」は「その仕事を遂行できるオブジェクトは何か」という決まり事を表し、メソッドは「何の仕事を依頼できるのか」という決まり事を表します(メソッド名は暗黙的に「何をするか」を表すため、メソッド名は非常に重要です)。さらにメソッドの引数と戻り値の定義は、仕事を依頼する際に「何を渡さなければいけないか」と、その結果「何が返ってくるのか」という決まり事を表しています。

ここで重要なのは、インターフェイスで明示されるのはすべて「何(What?)」であり、具体的な仕事の「どのように(How?)」ではないということです(Howを実装するのはクラスとなります)。

例えば以下のような単純なコードで考えてみましょう。

java

1interface A { 2 void doSomething(); 3} 4 5class X implements A { 6 public void doSomething() { 7 System.out.println("X"); 8 } 9} 10 11class Y implements A { 12 public void doSomething() { 13 System.out.println("Y"); 14 } 15}

この例では、Aインターフェイスが「規約」であり、Aという型のオブジェクトはvoid doSomething()という仕事をする、という決まり事(What)だけが定義されています。
そして、クラスXとクラスYは共にAインターフェイスを実装しており、すなわちXとYは、Aで定められた規約の具体的なHowを提供するというわけです。

これらのコンポーネントを利用する側のクラスとして以下のようなZクラスを考えてみましょう。

java

1public class Z { 2 3 public void method(A obj) { 4 obj.doSomething(); 5 } 6}

このZクラスのmethodを呼び出す場合、引数で定義されているA型であればどのようなオブジェクトでも渡すことができます。A型の契約を締結しているオブジェクトはdoSomethingメソッドを提供していることが保証されているからです。したがって、具体的にどのようなオブジェクトが渡されようとも(XでもYでもOK)、それがA型という規約を守っているのであれば、そのオブジェクトのdoSomethingメソッドを呼び出して正常に処理することができるという保証が生まれます。
それに対してA型を実装していない、つまりAという契約を締結していない他のオブジェクトは渡すことはできません。doSomethingメソッドが実装されている保証がないからです。

このようにインターフェイスというのは、あくまでも、あるオブジェクトと別のオブジェクト間の「仕事の依頼」に関する「決まり事」をコードとして明示するためのものであり、「クラスの継承」とは本質的に異なるものだということです。つまり「クラスの継承」は、既に実装された機能を再利用するための仕組みであるのに対して、「インターフェイス」はライブラリの「設計」における決まり事を定めるために重要だということです。
インターフェイスを一切使用しなくてもライブラリを設計・実装することは可能ですが、インターフェイスをうまく活用することで、汎用性や拡張性、保守性に優れたライブラリを設計することができるようになります。なので、JDKなどのライブラリにはインターフェイスがたくさんありますが、それらを利用するコードを書く場合には自分でインターフェイスを作成する必要性はあまりありませんよね?

インターフェイスを活用した設計としてデザイン・パターンと呼ばれるセオリーがあるので、興味があれば勉強してみてください。より理解が深まると思います。

投稿2017/03/24 07:28

amadablam

総合スコア402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kisaragizinzin7

2017/03/25 07:26

回答ありがとうございます! 継承と実装は全然違うものだったんですね! わかりやすくて掴めた気がします ありがとうございました!
guest

0

・継承について
「旧型マウス」と「新型マウス」を想像してください。
1-旧型マウスはクリックするとPCにクリック情報を伝えます。
2-新型マウスはクリックすると旧型マウスの機能に加え、クリックした強さを伝えます。

この時、「旧型マウス」と「新型マウス」を継承関係にすると「新型マウス」ではクリックした強さに関する実装だけを新規に作るだけで良くなります。

・実装について
「人間」と「マウスのボタン」と「PCのボタン」を想像してください。
1-「人間」はボタンを押すことができます。
2-「マウスのボタン」は押されることができます、このときクリックが発生します。
3-「PCのボタン」は押されることができます、このときPCの電源が付きます。

この時、「押された時の処理」をインターフェースにしておくことで「人間」は「押された時の処理」が実装されているもの「押す」ということができます。また、押したものがマウスのボタンなのか、PCのボタンのボタンなのかを識別しなくても良いところに利点があります。

投稿2017/03/23 08:21

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kisaragizinzin7

2017/03/23 08:45

回答ありがとうございます。 継承はベースのクラスから一部機能を追加変更したいときに使う 実装は公式みたいに「押された時の処理」というのを作っておいて、マウスのボタンでも使える、PCのボタンでも使えるみたいな感じですかね?
yona

2017/03/23 08:52

最初の理解としては十分だと思います、慣れた頃に再度調べたらいいですよ。
kisaragizinzin7

2017/03/25 07:19

ありがとうございました! 掴めた気がします! また調べてみたいと思います。
guest

0

C++のような一部の例外を除いて、Javaなど多くの言語では基底クラスは1つしか持てません。一方で、インターフェースは(メソッドが干渉するなどの事情がなければ)1つのクラスにいくつでも実装できます。

そのため、「特定のメソッドが呼べればいい」と言うかたちでいろんなクラスを共通して扱いたい場合は、継承でやらずにインターフェースとしたほうが、基底クラスを固定せずに済むので便利です。

投稿2017/03/23 07:34

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kisaragizinzin7

2017/03/23 07:38

回答ありがとうございます! 継承は1つ、実装は複数できるというのは知っていましたが、 継承と実装の違いはそこだけということでしょうか?
guest

0

どの本を見ても、継承から先に取り扱っているので誤解されやすい点だと思いますが、多態と継承は分けて考えるべきです。(多態はとりあえず、複数の型を基底クラスまたはインターフェイスクラスの変数として扱うためにあるとと考えてください。)

継承のみでも多態を使うことができますが、単一継承の制約の制約を抜きにしても、多態は実装とは結びつける必要はありません。

そのため、継承もインターフェイスを保証できるため”おまけ”として多態ができると考えておくと考え方はスッキリすると思います。

投稿2017/03/24 06:35

iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

0

継承と実装の違いについて、へんな例えになりますが例え話を書きます。

とある特殊部隊はビームが打ててロケットパンチが打てるパワードスーツを着ていることが出動条件となっています。

ベーシックパワードスーツはすでに完成しており、これを着るだけで特殊部隊の隊員になれますし、ビームも打ててロケットパンチが打てます。

隊員Aはベーシックパワードスーツをそのまま使います。これでビームもロケットパンチも打てます。

隊員Bはベーシックパワードスーツのビームを改造して、青色のビームが出るようにしました。ロケットパンチはベーシックなままです。

隊員Cはベーシックパワードスーツのロケットパンチを改造して、スピードをあげました。ビームはベーシックなままです。

隊員Dはなんとパワードスーツの規格に則って、自分でスーパーパワードスーツを作りました。ベーシックなものとビームとロケットパンチの性能は違いますが、特殊部隊の出動条件をきちんと満たしています。

着ているパワードスーツは全員違っても、全員ビームもロケットパンチも打てるので隊員として扱うことができます。

以上の話で、継承と実装を説明するのであれば、以下のようになります。

継承:隊員B、隊員Cのように、既存のパワードスーツをカスタムする
実装:隊員Dのように、自分で規格に則って作る

#追記
ある日、「特殊部隊隊員はパワードスーツに通信機器を取り付けること。本部と通信が出来ればなんでもよい」という通達がありました。隊員は各々パワードスーツを改造します。元々ベーシックパワードスーツには通信機器がないので、自分たちで取り付けることになりました。

隊員Aさんはスマホを取り付けました。
隊員Bさんはトランシーバーを取り付けました。
隊員Cさんはガラケーを取り付けました。
隊員Dさんは衛星電話を取り付けました。

全員、元々パワードスーツにそんな機能はありませんでしたが、本部と意思疎通は可能になりました。使っているものはバラバラですが、目的は果たしています。

これが実装の利点です。使う側が「この要件を満たして欲しい、でもこちらからはなにもベースになるものは出さない」状態でも、インタフェースというルールさえ実装すれば、ちゃんとお互い目的を果たすことができるのです。

例えばJavaのよく使われるインタフェースとしてjava.lang.Iterableというものがあります。

Java

1List<Integer> list = new ArrayList<>(); 2Set<Integer> set = new HashSet<>(); 3Queue<Integer> queue = new ArrayBlockingQueue<>();

ListとSetとQueueは動作する振る舞いはすべて違いますが、これらはすべてIterableを実装しています。Iterableを実装していると、拡張forに使えます。

Java

1for(Integer int : list) { 2} 3for(Integer int : set) { 4} 5for(Integer int : queue) { 6}

Iterableは「順番に要素を取り出せること」という要件が記述されているため、Iterableさえ実装したクラスであれば、forの処理で共通して使えることが保証されているのです。インタフェースとは「その機能を持っていることを保証するよ」という証明なのです。

投稿2017/03/23 08:13

編集2017/03/23 09:06
masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kisaragizinzin7

2017/03/23 08:36

回答ありがとうございます。 この話でいくと隊員Aをスーパークラスとして BにAを継承してビームメソッドをオーバーライド CにAを継承してロケットパンチメソッドをオーバーライド DにAを継承して両方のメソッドをオーバーライド したらいいと思ってしまうのですが、Dは実装になるんですかね?
masaya_ohashi

2017/03/23 08:51

それでも十分問題ないです。ちょっと例えが悪かったですね。追記します。
kisaragizinzin7

2017/03/25 07:17

追記載せていただいてありがとうございます! 感覚的にですが掴めた気がします! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問