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

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

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

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

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

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

Q&A

解決済

4回答

3285閲覧

間違った継承について

mr0237

総合スコア164

Java

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

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

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

0グッド

2クリップ

投稿2017/04/02 03:04

JAVAのオブジェクト指向を勉強・練習している者です。説明が下手ですいませんが、 
「スッキリわかるJava入門 第2版 (スッキリシリーズ) 」の(P431の)「間違った継承をするべきでない理由」にて

確かにHouseクラスを作った時点ではItemクラスを継承していても問題がないように思えます。しかし、これは単に
「たまたま現時点では実害がないだけ」であって、より忠実に現実世界の家やアイテムをまねようとクラスを改良
していくと次々と矛盾が生じます

と書かれているんですが、確かに以下のソースコードを継承してHouseクラスを作っても、問題がないように見えるんですね。

Java

1public class Item { 2 //省略 3 public int getDamege(){ 4 return 10; 5 } 6 //省略 7 } 8}

さらに、P436には

でも「HouseクラスにはgetDamege()があるけど、無視して使わない」ことにすればいいんじゃない?

と書かれており、確かにItemクラスを継承して、作成したHouseクラスの中にItemクラスから継承されたgetDamege()メソッドがありますが、それを無視して使わないようにすればいいと(私としては)思うんです。

しかし、

だめよ。「存在するけど実は使っちゃダメなメンバ」がいくつもあるクラスなんて、怖くて使えないわ

と書かれております。なぜ「存在するけど実は使っちゃダメなメンバがいくつもあるクラスなんて、怖くて使えない」と思ったのでしょうか?

そんなの無視して使わないようにすればいいと思うのですが、なぜ怖くて使えないのでしょうか?

なんらかのバグが生じるのですか?

よろしくお願いします。

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

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

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

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

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

guest

回答4

0

ベストアンサー

大規模な開発になると、実体のクラスではなく、スーパークラスやインタフェース型で設計することが多々あります。

よくある使い方としては、Listです。
Itemというクラス名、getDamageというメソッド名から推測するに、これはRPGで使う武器の類(どんなアイテムでも投げればダメージを与えられるゲームもあったからそういう意図も込みか)を表すものでしょうか。そして、実際どんなアイテムかを、このクラスを継承して作る、という構造になっていると思われます。
そしてそれをカバンのような、主人公がアイテムを持ち歩くためのものとしてListを使う場合、そのカバンにはいろいろなアイテムを入れたいので、**List<Item>**という形で使いたい、ということになります。そうすると、HouseクラスがItemを継承した場合、Houseオブジェクトをこのカバンに入れることができてしまうことが問題です。

「入れるだけなら何の問題もないじゃん?」と思うでしょう。しかしそうではありません。
カバンに入っているアイテムそれぞれに対して一括で何らかの操作・行動を起こしたい、というケースになった際、カバンのList内にあるItemをループして取り出すことになります。もちろん、**getDamageを使わないと考えていたHouseオブジェクトもその対象です。**しかし操作する時点でそんなことわかりません。もし入っていた場合、使う予定のなかったHouseオブジェクトのgetDamageメソッドを意図せずして使ってしまうことになるのです。instanceof演算子などでチェックする方法もなくはないのですが、そもそもそんな使い方をさせなければならない時点で設計として間違っています。

さらに、何らかのメソッドでItem型のオブジェクトを返すメソッドが存在したとします。この時も、返り値としてHouseオブジェクトを返すことが可能になってしまいます。しかしメソッドを使った側からはそれがItemであるということしかわからないので、何の疑いもなくgetDamageを使えてしまいます。

このように、不適切な継承をした場合、使う側が大変な迷惑を被ることになるのです。

投稿2017/04/02 04:30

編集2017/04/02 04:36
swordone

総合スコア20649

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

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

0

こんにちは。

「存在するけど実は使っちゃダメなメンバがいくつもあるクラスなんて、怖くて使えない」

適切に設計されたクラスに不必要なメンバが多数あるということは有りえません。
つまり、いい加減な設計がされていることが明らかなので、とても怖くて使えないということかと。

投稿2017/04/02 03:10

Chironian

総合スコア23272

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

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

0

この場合の「怖い」の対象は、コード自体に対してではなく、「そういうクラスを使わなければならない状況」に対する怖さであると考えれば良いでしょう。

寿司屋に弟子入りしたとして、その店では包丁として十徳ナイフを使っていたらどう思いますか。
「ここではこれを使うんだ」「ナイフはしっかり研いである」「ナイフ以外は滅多に使わないけどな」なんて言われたらどう思いますか。
師匠の技量はともかく、「ここで修行していていいのか?」と思いませんか。

物事を進めるためにはそれに最適の道具があって、できるだけ無駄なものは省かれていたほうが良いのです。
無駄なものがたくさんついた道具は、大は小を兼ねるとは言いつつも、初めての人が使うには不向きであったり、道具の本来の用途が見えなくなったりなどマイナス面も大きいのです。

投稿2017/04/02 05:36

akabee

総合スコア1947

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

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

0

お考えは半分正解です

「大は小を兼ねる」という考えは現実は必ずしも通じません。危険因子は存在しないに越したことはありません。(不正解部分)

逆に綺麗ごとばかり述べれば結局何も作ることができません。ルール、決まり事を作って運用側でカバーしてもらうところも現実には存在します。(正解部分)

投稿2017/04/02 05:08

HogeAnimalLover

総合スコア4830

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問