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

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

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

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

Q&A

解決済

4回答

4757閲覧

JAVA SE 8 [ interfaceのdefault実装について]

shun4develop

総合スコア26

Java

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

1グッド

0クリップ

投稿2016/01/14 14:16

interfaceの利点は
interfaceの実装先に特定のメソッドのOverrideを義務付けるとともに
同名関数の衝突回避をしながら擬似的な多重継承を可能にするようなものだと考えていました。
ところがJAVA SE 8からinterface内にdefault実装というものができてしまいまったせいで
私の中では整理がつかずabstract修飾子をつけたclassとの差が分からなくなってしまいました。

そもそものinterfaceの捉え方が間違っていたということが発覚し非常にショックです。

せっかくの申年ですし
interfaceとabstract classの違いを猿にでも分かるように説明いただきたいです。

(一般化した言い方ではなく具体例を出していただけると非常に助かります。)

よろしくお願いします。

退会済みユーザー👍を押しています

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

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

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

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

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

guest

回答4

0

ベストアンサー

java

1 2package com.test.swing.util; 3 4public class C implements A,B { 5 6 public void test() { 7 System.out.println("C test called."); 8 } 9 public static void main(String...args) { 10 11 C c = new C(); 12 13 c.test(); 14 15 A a = new C(); 16 17 a.test(); 18 19 B b = new C(); 20 b.test(); 21 } 22} 23 24package com.test.swing.util; 25 26public interface B { 27 default void test() { 28 System.out.println("C test() call."); 29 } 30 31} 32 33package com.test.swing.util; 34 35public interface A { 36 37 default void test() { 38 System.out.println("C test() call."); 39 } 40} 41

結果:
C test called.
C test called.
C test called.

default メソッドめちゃくちゃ便利じゃないですか。何を迷うとこあるんです?
継承先で集約できるんですよ。多重継承の逆版みたいな感じですね。
C.test を実装しない場合、構文エラーになりました。
まぁ、"default" な実装なので、名前は確かに衝突する可能性は高くなりますが、
2つの異なる振る舞いを1つに集約できるという点では、自分的には OK です。
回答になっていませんが。

投稿2016/01/14 15:11

ipadcaron

総合スコア1693

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

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

shun4develop

2016/01/14 15:22

なるほど。 つまり「衝突の可能性があることは間違いない」という認識で間違いないでしょうか?
ipadcaron

2016/01/14 16:57

失礼、 A のSystem.out.println("A called"); B の System.out.println("B called"); ですね。記述ミスったけど、結果は同じ。Cのオーバーライドしたやつしか呼べない。 衝突するから、なんですか、てな感じです。 A,B インターフェースは基本異なる動きが定義されています。 似てる処理を定義したものなら、なおさら継承クラスでオーバーライドして 規定実装を打ち消すべきだと思うのです。なによりも似てるインターフェース ならひとつにまとめるのが本筋でしょうし、場合によって使い分けるなら それ単体の継承クラスにすべきです。 似てない処理を定義しても、Cクラスでは2つのインターフェースを継承する 必要がある場合、A の test, B の test はやはり公開しても意味がありません。 というか継承した時点で存在意義が曖昧になる。曖昧なものを公開メソッドに してもCクラスの立場がなくなる気がします。 言語仕様として default メソッドが定義でき、継承するタイミングで規定実装 を打ち消すか、規定は規定として残しておくかは実装者に委ねるというのもあり だと思いますね。 だんだん、C++化していくというか、C++とは異なる路線を歩もうと努力して 結局変な方向に行っちゃうのは Java のデフォルトなんじゃないでしょうか。 そろそろ、オペレータ導入してほしいものです。λ式とかどうでもいいです。
guest

0

abstract classはクラスなので、継承しないと使えません。
他のクラスを継承したクラスに更にこのクラスの機能を加えて…という芸当はできません。
しかし、クラスフィールドを持つことができ、独立した情報を持つことができます。
ほか、コンストラクタなどを定義することもできます。

一方interfaceは継承関係に縛られずに実装できます。
一方、定数でないフィールドを宣言できないので、インタフェースが情報を持つということができません。
あくまでインタフェースは操作の入り口なので、「操作方法」を提供しているに過ぎず、
デフォルト実装は「既定の操作」を設定しているだけです。

投稿2016/01/14 14:22

swordone

総合スコア20651

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

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

shun4develop

2016/01/14 14:51

例えばAとBという二つのインターフェースを実装したCというクラスがあり、AとBそれぞれにtestというメソッドを定義しdefaultの処理が実装されている場合に Cクラス内でtestをOverrideしないままC.test()を実行したら関数の衝突が起きますよね? これはdefault実装という概念が生まれる前には起きなかったはずです。 ならばなぜそんな概念が生まれたのでしょうか。
swordone

2016/01/14 15:02

そもそもdefault実装が生まれる前には「testをOverrideしないまま実行」ということが起こりえないことのはずです。 それはそれとして、機能の中には予め「こういう機能として使わせたい」という設計がありえます。その設計がインタフェースから定義できるものなら定義しておいたほうが紛れが少なくて済みます。
guest

0

Java だけでなく、最近のクラスベースのオブジェクト指向に共通しそうな話題ですね。

質問者の開発言語経験など背景がちょっと解りませんが、文面を見ると実装だけの考えで捉えすぎているように見受けられます。もっと設計に比重を置いた捉え方ができるようになると、たぶん、その質問/疑問は解消するのではないでしょうか?

オブジェクト指向でのクラス継承を親子の縦方向の関係とすると、インターフェイス実装は共通性のある横方向の関係をイメージすると良いかもしれません。クラス継承を行う場合は必ず親は1つ。インターフェイス実装を行う場合は複数可能で、Java の場合はこれらを単体でも、組み合わても使える言語になっています。インターフェイスにデフォルト実装が加わってもこの関係は変わりませんし、無理してデフォルト実装を使う必要はありません。(効果的に使えるならば使うほうが明らかに便利だと思いますが)

※ ただし、同じメソッド名のデフォルト実装を複数使う場合は多重継承における菱形継承問題と同様の問題が発生するため、ipadcaron さんが回答されているコードの通り、明示的に override しなければコンパイルエラーとなるはずです

設計を度外視した実装だけで考えれば、abstract class を使っても、それと同じような default 実装の interface でも、同じ結果を得るための処理は実現できるでしょう。ただし、それぞれのクラス構成や結果を得るための思想は全く異なります。クラスやらの要素の在り方が設計上の違いとして表れているはずです。

クラス継承とインターフェイス実装の参考になりそうなもので思いつくのは、例えば、デザインパターンでの Template Method と Strategy 辺りが(ちょっと難しいかもしれませんが)それぞれ参考になるのではないでしょうか?

インターフェイスの凄さは、大量の異なるクラスを横断的に扱うような状況など、それなりの規模にならないとなかなか実感しないかもしれませんが、効果的に使えるようになると保守性も上がりますし、とっても便利ですよ。まぁ、あとは集約/合成(コンポジション)が解るともっと面白くなると思います。

投稿2016/01/14 15:59

ps13zier

総合スコア433

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

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

shun4develop

2016/01/14 16:38

回答ありがとうございます。 私は現在、学生をやっておりまして、今年度1年かけてJavaの勉強を授業でやってきました。現在の講師の方がinterfaceとabstract classの違いについて説明してくれましたが、文法の話ばかりで「設計」についての話は全くなかったのでps13zier様の回答にただただ「なるほど」と思うばかりです。 まだまだJavaの様々な機能や考え方について本質的な理解はできていないですが、 これからは設計の面も念頭に置いて少しずつ理解を深めていきたいと思います。 デザインパターンについて何かおすすめの書籍などあれば教えていただきたいです。
ps13zier

2016/01/15 03:55

デザインパターンのおすすめの書籍ですか?これは汎用的に使える知識ですし、より多くの人に教えてもらう方が有意義ですから、新しく別な質問を行ってみるのも良いかもしれませんね。今なら書籍以外にもウェブサイトでの良質な解説もあるかもしれませんし、幅広く意見を求めてみては如何でしょうか? 私の場合はGoF本と呼ばれる『オブジェクト指向における再利用のためのデザインパターン』からデザインパターンを齧り始めたので、ここ最近の本とかは読んでないんですよね。正直、この本は開発経験の少ない初学者にとって極めて難解な上、新品なんかだと学生の懐にはとても痛いでしょうから、他で代用できるなら無理する必要はないでしょう。ただし、内容は(難しいのが問題なだけで)素晴らしいですし、カタログとしてもずっと使える良書であるのは確かです。 老婆心ながら、デザインパターンは設計で使える要素でしかないので万能なものではありません。ただし、それを足がかりにオブジェクト指向の分析や設計の勉強も手が出しやすくなりますので、漠然としていた足りない部分が勉強した分だけ自分で具体的に見えてくると思います。道は険しいと思いますが、無理せずコツコツ続ける事が大切です。
guest

0

default実装を衝突の可能性が生まれるのにいいのか?
なら多重継承を禁止する意味がないじゃないか!
というパニック状態のままabstractが云々...と沼にはまってしまいました。

改めて考えると自分の中で
多重継承の利点がコードの再利用のみに偏っていました。

JAVAでは何故、多重継承が禁止されているのかと考えた時に
「多重継承の存在によってコードの再利用が乱用され
本来のオブジェクト指向から離れて行ってしまう可能性があるから」なのでは?
と自分の中で合点がいきました。

そして衝突が起きる場合は構文エラーを吐いてくれるんですね!!
ipadcaron様ありがとうございます。
「なんだこれ意味ねぇじゃん。使わねーよ。」とか思って試そうともしなかった少し前の自分を
ぶん殴りたいです。

検証不足のまま質問してお二人の貴重な時間を割いてしまい申し訳ありませんでした。
反省します。

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

投稿2016/01/14 15:56

shun4develop

総合スコア26

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問