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

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

ただいまの
回答率

91.02%

  • Java

    12149questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 3
  • VIEW 551

javacurry

score 38

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+4

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

ちなみに「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/17 10:06 編集

    JAVAが浅いせいかピンとこない部分もあるので何度も読み返します。これからは、まずインターフェースを使うことで考えてみます。

    まだ基本ができていないのに深いところまで考えてしまいました。じゃんけんプログラムを作ろうとして、人や手をそれぞれオブジェクトと見ようとしたときに、今回の疑問がわいてきましたが少しすっきりしました。アドバイスありがとうございました!

    キャンセル

  • 2018/01/17 10:43

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

    キャンセル

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

  • ただいまの回答率 91.02%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    12149questions

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