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

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

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

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

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

Q&A

3回答

779閲覧

デッドコードじゃないんだが到達不能?

rnosh

総合スコア171

Java

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

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

0グッド

0クリップ

投稿2019/08/07 08:27

前提

既存システムの単体試験をしています。
実装から参画したため、前任者の設計書通りに実装しテストに移ったわけですが、スケジュールの都合上しっかりソースを読める時間がなく、取り掛かったという背景があります。
ちょっと僕の経験内では想定外の既存実装がありまして、タイトルの通りコンパイル上はデッドコードにはならないものの、改修したのに通せない箇所が出てきました。
継承についてなのですが、めちゃくちゃ知見が深いわけではないので、これってどういうこと?つまりどうなるの?的なところをご教示いただけたらと思います・・・。

該当のソースコード

Java

1public class aLogic() { 2 public void execute() { 3 aDao dao = new aDao(); 4 String hoge = dao.selectHoge(param) 5 } 6} 7 8public class aDao { 9 public String selectHoge(param) { 10 // 処理 11 } 12}

ここまではごく一般的な流れだと思います。
別の起動プロセスから動く以下のコード・・・

Java

1public class bLogic() { 2 public void execute() { 3 aDao dao = new bDao(); 4 String hoge = dao.selectHoge(param) 5 } 6} 7 8public class bDao extends aDao { 9 public String selectHoge(param) { 10 // 処理 11 } 12}

上記のように、別の起動プロセスを経て動くbLogicがDaoのインスタンス生成時にaDaoを、aDaoを継承したbDaoでnewするといったことになっています。。。

aDao、bDaoどちらのselectHogeも全く同じ処理をしているため、同様に改修したのですが、bLogicから飛ぶのはaDaoのselectHoge。

bDaoのselectHogeが別のところから参照されていればいいのですが、当該メソッド以外では呼び出されておりません。(何ならbDao自体、このインスタンス生成時以外使用されていない・・・)

聞きたい事

class単位でのテストは可能ですが、一連の処理の流れをテストしたいとき、まあどうやってもbDaoのselectHogeに突入することなく、aDaoの方に行ってしまうので、改修したbDaoのselectHogeに到達できず、といったところです。

継承の基本的なところについては理解しているつもりですが、このような使い方を今までにしたことがないので、戸惑っております。
これがどうしてもスタンダードな処理だとは、思えないのですが。

インスタンス生成の時点でおかしなことやってるから**「通らない / 通ってない」って判定で正しいのでしょうか?
それとも継承という観点からみると、処理内容が全く同じであるなら、
「通っている」**という判定になるなんてことまさかまさかであったりしますか?

愚問なのかもしれませんが、ご教示頂けますよう、よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

Java6

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

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

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

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

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

Zuishin

2019/08/07 08:57

@Override がついていないのでは?
guest

回答3

0

bDaoが継承しているメソッドが、実は継承していないということはありませんでしょうか。

メソッド名が違う、引数の型が違うなど。

投稿2019/08/07 08:54

A-pZ

総合スコア12011

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

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

swordone

2019/08/07 09:30

「引数の型が違う」はありそう。 コードに引数の型ないし。
guest

0

A-pZさんの回答で合っている気がします。

オーバーライドと呼び出し方法のサンプルですが。
理解できていないと想定外の動きになります。

単純にオーバライドするしないの話と、
インスタンスの型でなく宣言の型でメソッドが呼ばれるのがわかると思います。

メソッド名が違う、引数の型が違うなど。

を確認してみては、どうでしょう

java

1public class Hoge { 2 public static void main(String[] args) { 3 Hoge hoge = new Hoge(); 4 Hoge who = new Foo(); // who 5 Foo foo = new Foo(); 6 7 System.out.println(hoge.say(hoge)); // Hoge:hoge 8 System.out.println(hoge.say(who)); // Hoge:hoge 9 System.out.println(hoge.say(foo)); // Hoge:hoge 10 System.out.println(); 11 12 System.out.println(who.say(hoge)); // Foo:hoge 13 System.out.println(who.say(who)); // Foo:hoge not Foo:Foo 14 System.out.println(who.say(foo)); // Foo:hoge not Foo:Foo 15 System.out.println(); 16 17 System.out.println(foo.say(hoge)); // Foo:hoge 18 System.out.println(foo.say(who)); // Foo:hoge not Foo:Foo 19 System.out.println(foo.say(foo)); // Foo:Foo 20 21 } 22 public String say(Hoge h) { 23 return "Hoge:Hoge"; 24 } 25} 26class Foo extends Hoge { 27 @Override 28 public String say(Hoge h) { 29 return "Foo:Hoge"; 30 } 31 32 public String say(Foo f) { 33 return "Foo:Foo"; 34 } 35}

投稿2019/08/07 12:53

編集2019/08/07 13:05
momon-ga

総合スコア4820

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

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

0

実際に動かしたいのはbDao#selectHogeですよね?
インスタンス化の際にaDao dao = ...としているのでアクセスできるのはaDaoのメソッドだけです。
インスタンス化したdaoはaDaoクラスだからです、という説明で大丈夫でしょうか?

実際のインスタンスには継承したbDaoを含みますが、aDaoとして扱う以上はaDaoクラス以外のフィールドもメソッドも使うことは出来ません。

したがってこの場合はbDao dao = new bDao();とするのが良いでしょう。

上記回答は誤りです。
他の回答者様の回答やコメントの通り、引数違いではないでしょうか。
bDaoに同じメソッド名で別の引数を持つメソッドを作ってしまうと呼び出すことが出来ません。
これはaDao dao = でインスタンス化している為、aDaoのメソッドシグネチャしか認識できない為です。


ご指摘を頂いたので再確認。
確かによく考えればオーバーライドされたメソッドが呼ばれますね。
(自分でもインスタンス化でbDaoになってると言いながら…)

Eclipseのハイライト見てA側だなと思って確認せず回答してしまいました。
誤った情報を載せてしまい申し訳ございません。

EclipseのHC

検証コードを分かりやすく変更
paiza.ioで実行

Java

1import java.util.*; 2 3public class Main { 4 public static void main(String[] args) throws Exception { 5 6 ADao dao = new BDao(); 7 System.out.println(dao.aString); 8 //System.out.println(dao.bString); 9 System.out.println(dao.procA()); 10 //System.out.println(dao.procB()); 11 //System.out.println(dao.procA("追加引数")); 12 } 13 14 public static class ADao { 15 public String aString = "AaString"; 16 17 public String procA() { 18 return "AprocA"; 19 } 20 } 21 22 public static class BDao extends ADao { 23 public String aString = "BaString"; 24 public String bString = "BbString"; 25 26 @Override 27 public String procA() { 28 return "BprocA"; 29 } 30 31 public String procA(String exArg) { 32 return exArg; 33 } 34 35 public String procB() { 36 return "BprocB"; 37 } 38 } 39}

投稿2019/08/07 09:22

編集2019/08/07 12:56
S_kawa

総合スコア156

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

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

momon-ga

2019/08/07 12:11

> String ret3 = dao.procA(); //○ これはADao#procA オーバライドされてるなら、BDaoのprocAでしょ?
S_kawa

2019/08/07 12:57

@momon-ga さん ご指摘ありがとうございます。ごもっともです。 回答は訂正させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問