現在学習しているjavaの参考書で不明点があります。
プログラミング初心者で要領を得ない部分があると思いますが、どうぞ宜しくお願いいたします。
※ 文章の太字が疑問部分です。
java
1public class Hero { 2 String name; 3 int hp; 4 public boolean equals(Object o) { 5 if(this == o) { return true; } 6 if(o instanceof Hero){ //(1) 7 Hero h = (Hero)o; //(2) 8 if(this.name.equals(h.name)) { //(3) 9 return true; 10 } 11 } 12 return false; 13 } 14}
java
1public class Main{ 2 public static void main(String[] args){ 3 Hero h1 = new Hero(); 4 h1.name = "ミナト"; 5 h1.hp = 100; 6 Hero h2 = new Hero(); 7 h2.name = "ミナト"; 8 h2.hp = 100; 9 if(h1.equals(h2) == true){ 10 System.out.println("同じ内容です"); 11 } else { 12 System.out.println("違う内容です"); 13 } 14 } 15}
疑問1
※ //のコメントは自分なりの理解を書いたものです
<Heroクラス>
(1) if(o instanceof Hero){ //oをHero型に代入可能かどうかをチェック
(2) Hero h = (Hero)o; //(1)が代入可能ならoをHero型と見なしてhに代入
(3) if(this.name.equals(h.name)) //this.name(つまりh1.name)がh.name(つまりh2.name)と等しいかどうかをチェック
(a) (1)でチェックする理由がよく分かりません。
(b) (1)で代入可能かチェック済みなのに、わざわざ(2)でoをhに実際に代入(ダウンキャスト)する意味が分かりません。
つまり次のように(2)は省略しても両者の比較は可能なのでは?という疑問です。
ちなみに(2)を省略する形で変更したコードが次です。
(1) if(o instanceof Hero) //oをHero型に代入可能かどうかを調べる
(2) //Hero h = (Hero)o; //省略
(3) if(this.name.equals(o.name)) //this.name(つまりh1.name)がo.name(つまりh2.name)と正しいかどうかをチェック
疑問2(新たな疑問)
疑問1で変更したコード((2)を省略したコード)が下記です。
これをEclipseで動かしてみました。
java
1public class Hero { 2 String name; 3 int hp; 4 public boolean equals(Object o) { 5 if(this == o) { return true; } 6 if(o instanceof Hero){ //(1) 7 //Hero h = (Hero)o; //(2)*省略* 8 if(this.name.equals(o.name)) { //(3) 9 return true; 10 } 11 } 12 return false; 13 } 14}
すると、(3) if(this.name.equals(o.name))の行で、
「name は解決できないか、フィールドではありません」というエラーが出てしまいました。
このエラー原因を自分なりに調べた結果が以下です。
変更前の(3)の「h.name」で問題なく動いたのは、Heroクラスにてnameフィールドを定義していることでh.nameを使用できたため。
これに対し変更後の③では、oの継承元であるjava.lang.objectにおいてnameフィールドが定義されていないにもかかわらず、「h.name」が「o.name」と変更されてしまったため、o.nameを使用できないのでエラーになってしまった。
※ つまり子クラス型変数(ここではhのこと)を親クラス方変数(ここではoのこと)に代入した場合、子クラス型変数にしかないメソッドが親クラス方変数側から呼び出せないのと同じ理由。
つまり、「疑問1」の(b)の疑問の解答は上記(つまりnameフィールドを使用したいから)だと推測しましたが、この認識で合っているでしょうか?
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/16 04:41 編集