【Java】継承したクラスをインスタンス化した時のイメージ


はじめに

Javasilver勉強中に????になったことを自分に刻むためのメモ

今回の????となった問題

※著作権とかあるかわからないですが、怖いのでそのままではないです。

パッケージ構成
test1
┗Human.java
test2
┗Engineer.java
┗Main.java

Human.java
package test1;

public class Human {
  private String name;

  protected String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}
Engineer.java
package test2;

import test1.Human;

public class Engineer extends Human {
}
Main.java
package test2;

public class Main {
  public static void main(String[] args) {
    Engineer e = new Engineer();
    e.setName("おなまえ");
    System.out.println(e.getName());
  }
}
Main.java実行結果
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    メソッド getName() は型 Human で不可視です

    at test2.Main.main(Main.java:7)

ソースを追ってみる

・Humanクラスを定義
 private のフィールドnameをGetter、Setterで使うDTOみたいなクラス

・Engineerクラスを定義
 Humanクラスを継承(しただけ)

・Mainクラス
 mainメソッドでEngineerクラスをインスタンス化
 Setterで値をセット
 Getterで値をとってきて出力(しようとしてコンパイルエラー(なんで!!))

 

当時の思考回路


・あ!!! Getterがprotectedになっている
・つまり、Getterにアクセスできるかどうかの問題、、、
・protectedはサブクラスか同じパッケージから利用可能...
・MainとEngineerクラスは同じパッケージ...
・答えはセットした値がそのまま出力されるだぁぁぁぁ

Main.java実行結果
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    メソッド getName() は型 Human で不可視です

    at test2.Main.main(Main.java:7)

(撃沈)

どこが間違っていたか

・protectedはサブクラスか同じパッケージから利用可能...
これと、
Engineer e = new Engineer();の時にどのようなインスタンスが生成されているか。

実際の動き

Engineer e = new Engineer();

を実行すると、

ではなく(重要)、


こうなっている。

EngineerクラスにHumanクラスの内容がコピペされてインスタンス化(上)されるのではなく、
HumanクラスとEngineerクラスの性質を併せ持ったインスタンスが生成されている(下)。

ので、エラーになっているところは、

こうなっている。

エラーメッセージにも『メソッド printInfo() は型 Human で不可視です』となっているので、
getName()はやはり、Humanクラスのものになっているようです。

Getterをpublicにしてみる

Human.java
package test1;

public class Human {
  public String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}
Main.java実行結果
おなまえ

できた。

余談

Humanクラスを無名パッケージに入れるとそもそもアクセスできない。
無名パッケージに何かしらのパッケージからアクセスできないので、

Human.java
test2
┗Engineer.java
┗Main.java