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

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

ただいまの
回答率

91.02%

  • Java

    12087questions

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

  • オブジェクト指向

    242questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

サブクラスで使わないこともあるメソッドを持った親クラスを作ってもよいのでしょうか?

解決済

回答 5

投稿

  • 評価
  • クリップ 7
  • VIEW 771

koikuti

score 21

継承先で使わないこともあるメソッドを持ったスーパークラスを作成してもよい?

クラスA, B, C, Dを作成するとき、
クラスAにはa, b, cメソッド
クラスBにもa, b, cメソッド
クラスCにはa, cメソッド
クラスDにはb, cメソッド
(異なるクラスにおいても、同じ名前のメソッドは同じ処理内容)
を作る持たせることになったのですが、
同じ内容のメソッドを書くのは面倒なので、
スーパクラスとなるクラスSを作ろうと考えました。

クラスSにはa, b, cメソッドすべてを持たせようと思ったのですが、
クラスCにとっては、bメソッドは不要。
クラスDにとっては、aメソッドは不要。
となるので、クラスSにすべてのメソッドを持たせてはいけないのではないかと思いました。

このようなクラス設計はありなのでしょうか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 5

+14

上の質問文を見ていると、「コードを共通化するため」に継承を利用しようとしていますが、それは本来の使い方ではありません

リスコフの置換原則という言葉があって、端的に言えば「コード上で基底クラスの現れるところには、どの派生クラスをもってきても問題ないようにしないといけない」ということです。

上の状況では、ABCDを統一的に扱うためではなく、コードを省略するためだけに親クラスのSを用意しているようですが、これは本来的な親クラスの役割ではありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 09:23

    リスコフの置換原則。初めて聞くものでした。
    確かに、私がやろうとしていることはコードの共通化が目的で、
    A、B、C、Dを統一的に扱うため(S s = new A(); としてSとして扱い、S.a や S.c と処理を行うことですよね?)ではありませんでした。
    どうやら、継承をどういうときに、どうやって使うのか、がまだわかっていないということがわかりました。
    ありがとうございます。

    キャンセル

checkベストアンサー

+3

他の方も書いている通り、よくないやり方です。

処理を共通させるのが目的であれば、他の方法があります。

方法1. デフォルトメソッドを持ったインターフェースを実装する

デフォルトメソッドaを持ったインターフェース1
デフォルトメソッドbを持ったインターフェース2
デフォルトメソッドcを持ったインターフェース3
をそれぞれ作成し、
クラスAにはインターフェース1,2,3を実装
クラスBもインターフェース1,2,3を実装
クラスCにはインターフェース1,3を実装
クラスDにはインターフェース2,3を実装
というふうにすれば、質問内容の通りのことができるはずです。
(但し、デフォルトメソッドもフィールドを使用できない等の制約があるので、必ずしもできるとは限りませんが・・・)

方法2. 処理の委譲を行う

メソッドaを持ったクラス1
メソッドbを持ったクラス2
メソッドcを持ったクラス3
をそれぞれ作成し、
クラスAのフィールドとしてクラス1,2,3を持たせ、クラスAのメソッドa,b,c内にて、それぞれクラス1,2,3のメソッドを呼び出すようにする
クラスBのフィールドとしてクラス1,2,3を持たせて同様の事を行う
クラスCのフィールドとしてクラス1,3を持たせて同様の事を行う
クラスDのフィールドとしてクラス2,3を持たせて同様の事を行う
というふうに実装するやり方です。
継承は元々、制約が大きいので、委譲による継承という方法があるのです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 09:42

    java8から、インターフェースに実装を持たせられるようになったみたいですね。
    ずっと、インターフェースは処理の中身のないメソッドしか持てないものだと思っていました。
    方法1. のやり方がまさに、こうできないかな~と思っていたやり方です。
    委譲による継承という方法も初めて知ったので覚えておきます。

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

    キャンセル

  • 2018/01/19 10:29

    > java8から、インターフェースに実装を持たせられるようになったみたいですね。

    まじでー! しばらく java 触ってないので知りませんでした。いいなあ・・・!
    勉強になります・・・ (´人`)

    キャンセル

+1

異なるクラスにおいても、同じ名前のメソッドは同じ処理内容

同じ内容のメソッドを書くのは面倒なので、

この辺がキモなんですよねきっと。

メソッドの内容がどういったものになるかにもよると思うのですが、たとえば

  • クラスAには「インターフェースA」「インターフェースB」「インターフェースC」
  • クラスDには「インターフェースB」「インターフェースC」

のように実装し、

別途 Utility クラスなどを作って
「インターフェースAを引数として受け取り、処理を行うメソッド」
などを作成。

a, b, cメソッドで Utility のメソッドを呼ぶ。

とか どうでしょうか・・・?

(私もこの辺の共通化のセンスがイマイチなので 一案程度で流してください)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/18 20:19

    処理とデータの組み合わせが交錯している状態を整理し、処理とデータを分離するという考え方で、これは原型ではないですがVisitorパターンの応用例だと思います。各処理が共通不変であることが確定しているなら、良い方法と思います。
    ちょっとずつ処理を変える必要があるなら、単純にインタフェース継承のほうが良いかもです。

    キャンセル

  • 2018/01/19 09:53

    お二方とも。ありがとうございます。
    今回は、インターフェースのデフォルト実装で解決しようと思います。

    が、初めて知ったのですが、Visitorパターンというものがあるのですね。
    ちょっと、すぐには自分の設計に組み込めないので、腰を据えて考えてみます。
    wikiを読んだ感じ、この方法でも解決できる気がしているので今後のために。

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

    キャンセル

+1

クラスの使用者が混乱すると思われるので避けたほうがよい設計だと思いますが。

大人の都合上どうしても無理でしたら、サブクラス側で不要なメソッドに対してはjava.lang.UnsupportedOperationExceptionをthrowする形にしてくださいな。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

考え方からするとやめたほうがいいと思います。

仮にクラスEが出来た時、cメソッドは必要でしょうか。
スーパークラスの共通メソッドは継承した各クラスで使う
スタンダードなメソッド(振る舞い)のみにするべきです。

設計上、クラスA,B,C,Dはどのような関係になるのでしょうか。
密接な関係があれば、考え方が正しかもしれませんが
単純に同じ処理ということであれば、
共通クラスなど別で考えたほうがいいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 09:33

    A,B,C,Dは全て初めてユーザの入力を受け付ける業務ロジックで、
    例えば、
    A:一般会員の新規登録&ログインク処理ラス
    B:登録済み一般会員のログイン処理クラス
    C:特別会員の新規登録&ログイン処理クラス
    D:登録済み特別会員のログイン処理クラス
    のようなもので、似たような処理を行う、完全に(?)別々のクラスでした。

    身内グループ内でも、それは入力値チェッククラスみたいな共通クラスを作ったほうがいいんじゃない?
    と指摘を受けました。

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

    キャンセル

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

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

関連した質問

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

  • Java

    12087questions

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

  • オブジェクト指向

    242questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • トップ
  • Javaに関する質問
  • サブクラスで使わないこともあるメソッドを持った親クラスを作ってもよいのでしょうか?