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

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

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

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

Q&A

解決済

1回答

6706閲覧

インターフェースと継承の使い分けについて

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

0グッド

4クリップ

投稿2018/01/16 06:25

インターフェースと継承を使い分ける場面がわかりません。特にabstractクラスとインターフェースが似ている気がします。

調べてみてインターフェースが別名「契約」と呼ばれるのは型を保証してくれて、あるメソッドを必ず持っていることで実装したクラスも同様に同じメソッドを持つ保証があるということと、あとはフィールドがstatic finalであるということはなんとなくわかりました。ただabstractクラスが同じようにメソッドが定義されないことで子クラスが同じメソッドを持つという部分が似ていて、どういう場面で継承を使うのか混乱しています。みなさんが実際にどういう場面で、どういう考えからそれぞれを選択しているのか教えていただけると参考になります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

かならずしも一般的な原則ではないと思いますが、自分はこんな風に考えることが多いです。

ちなみに「interface」は「機能」を表すと捉え、「(abstract or concrete) class」は「特定の実装」を表すものと捉えます。

###interface

オブジェクトを設計する際、備えるべき機能の定義は大抵interfaceとして考えます。特に

(I1) 特定のメソッドの引数に渡したいもの。または特定のメソッドの戻り値になるもの。

ちょっと言葉が足りないですね。より厳密に言うなら「複数の異なる具象クラスのインスタンスを扱うようなメソッドにおいて引数や戻り値の型になるようなもの」はabstract classではなくinterfaceとして考えるといった方がよいと思います。

引数を「interfaceではなくabstract classにする」のは(非常に大雑把に言うなら)そのメソッドが引数に渡されるインスタンスに対して必要以上の前提を置く(実装にかかわる詳細にアクセスしようとしているかも知れない)ように見えてあまりよいことに思えません。これは単純に「常にそうだ」と言えるようなものではなく場面によります。

なお、実引数を渡す際に

  • 具象クラス(名前付きクラス)のインスタンス
  • 具象クラス(無名クラス)のインスタンス
  • ラムダ式

等々の方法がありますが、特に強調したいのは「型」を表す際にメソッドが一つしかないようなものはinterface(典型的にはFunctionalInterfaceアノテーション付きのinterface)として定義しておくとラムダ式が使え大変重宝します。関数型プログラミングという言葉を聞いたことがあるかも知れません。特にjava.util.Arrays#sort(T[] a, Comparator<? super T> c)のようなメソッドを定義したい場合、interface(FunctionalInterface)とラムダ式は大変使い勝手がよいものです。

(I2)複数の機能を継承させたい(mix-inさせたい)場合

多用するわけではありません。しかし、たまにそういうことがしたくなる場合があります。簡単にいえば多重継承的なことがしたくなった時ということになります。こういう場合はインターフェースにするしかありません。抽象クラスにせよ具象クラスにせよ、あるクラスへ継承できるクラスは一つのみに制限されるからです。

###abstract class

よく考えてみると・・・これあまり使いません。インターフェースでは記述不可能な「共通的な実装」(典型的にはインスタンスフィールドによる実装)を備えさせたいときは使うことになりますが・・・。

抽象クラスは「ライブラリーを提供する場合」「ある程度大きな規模の応用プログラムにおいて、互いに重なりあう機能を備えたクラスがいくつも出てくるような場合」ならよく使われる気がします。しかしながら「機能に重なりがあるようなクラス群がそれほどないような応用プログラムを書く場合」では登場する機会が全然ないことも多いと思います。


余談:

ところでオブジェクト指向に備わったこうした機構について考えるのは「ある程度複数な機能を実装する」とか「既に作ってしまった機能に手を入れたい」というような設計をを繰り返しやりながら「あー設計がいけてない!」という経験をある程度つまないとなんでそういう考え方をするのかがなかなか分かりずらいと思います。

逆にいえばそうした「なんてイケテナイ設計なんだ!」と感じる経験をつむにつれ「こういう場合はこうして、ああいう場合はこうしたほうが・・・」という考えが自然にわいてくるような気がします。

投稿2018/01/16 07:35

編集2018/01/16 22:28
KSwordOfHaste

総合スコア18394

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

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

退会済みユーザー

退会済みユーザー

2018/01/17 01:06 編集

JAVAが浅いせいかピンとこない部分もあるので何度も読み返します。これからは、まずインターフェースを使うことで考えてみます。 まだ基本ができていないのに深いところまで考えてしまいました。じゃんけんプログラムを作ろうとして、人や手をそれぞれオブジェクトと見ようとしたときに、今回の疑問がわいてきましたが少しすっきりしました。アドバイスありがとうございました!
KSwordOfHaste

2018/01/17 01:43

シンプルなものから始めるのはよい方法と思います。ただオブジェクト指向は「複雑なものをどうスッキリさせるか」という場面で真価を発揮するのでシンプルな題材だと逆に良し悪しの判断が難しいかも知れません。題材そのものは簡単に見えるジャンケンですが、何をクラスとしてモデル化しどういう機能にするかは必ずしも「簡単」なことでもない気がします。何人かのプログラマーが同じジャンケンプログラムを作ったとしても結構違ったものが出来上がるかも知れませんね。初心者の方に限らず「クラスやインターフェースがまったく登場しないコード」になる確率もかなり高いと思いますw;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問