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

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

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

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

オブジェクト指向

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

Q&A

解決済

5回答

5888閲覧

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

koikuti

総合スコア50

Java

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

オブジェクト指向

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

0グッド

7クリップ

投稿2018/01/18 05:38

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

クラス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にすべてのメソッドを持たせてはいけないのではないかと思いました。

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

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

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

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

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

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

guest

回答5

0

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

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

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

投稿2018/01/18 05:50

maisumakun

総合スコア145184

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

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

koikuti

2018/01/19 00:23

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

0

ベストアンサー

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

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

方法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/18 06:11

編集2018/01/18 06:15
LineOfLightning

総合スコア253

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

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

koikuti

2018/01/19 00:42

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

2018/01/19 01:29

> java8から、インターフェースに実装を持たせられるようになったみたいですね。 まじでー! しばらく java 触ってないので知りませんでした。いいなあ・・・! 勉強になります・・・ (´人`)
guest

0

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

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

投稿2018/01/18 08:40

umyu

総合スコア5846

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

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

0

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

 

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

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

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

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

のように実装し、

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

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

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

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

投稿2018/01/18 06:39

編集2018/01/18 08:47
sk_3122

総合スコア1126

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

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

退会済みユーザー

退会済みユーザー

2018/01/18 11:19

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

2018/01/19 00:53

お二方とも。ありがとうございます。 今回は、インターフェースのデフォルト実装で解決しようと思います。 が、初めて知ったのですが、Visitorパターンというものがあるのですね。 ちょっと、すぐには自分の設計に組み込めないので、腰を据えて考えてみます。 wikiを読んだ感じ、この方法でも解決できる気がしているので今後のために。 ありがとうございました。
guest

0

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

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

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

投稿2018/01/18 05:58

szk.

総合スコア1400

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

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

koikuti

2018/01/19 00:33

A,B,C,Dは全て初めてユーザの入力を受け付ける業務ロジックで、 例えば、 A:一般会員の新規登録&ログインク処理ラス B:登録済み一般会員のログイン処理クラス C:特別会員の新規登録&ログイン処理クラス D:登録済み特別会員のログイン処理クラス のようなもので、似たような処理を行う、完全に(?)別々のクラスでした。 身内グループ内でも、それは入力値チェッククラスみたいな共通クラスを作ったほうがいいんじゃない? と指摘を受けました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問