Javaの継承関係にあるクラスではサブクラスのインスタンスには必ずスーパークラスのインスタンスに相当する部分が含まれており、スーパークラスのメソッドなどを使用することができる。
この特徴を利用すれば、サブクラスのインスタンスを、スーパークラスのインスタンスとして使用することができる。
ParentHumanクラスを継承するChildHumanクラスがあったとする。
ParentHuman.java
public class ParentHuman {
private String name;
private int age;
private String gender;
public ParentHuman() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "ParentHuman [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
}
ChildHuman.java
import java.time.LocalDate;
public class ChildHuman extends ParentHuman{
private LocalDate birthday;
public ChildHuman(String name, int age, String gender, LocalDate birthday) {
super(name, age, gender);
this.birthday = birthday;
}
public LocalDate getBirthday() {
return birthday;
}
public void setBirthday(LocalDate birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "ChildHuman [birthday=" + birthday + "]";
}
}
サブクラスのインスタンスを生成後、生成したインスタンスをスーパークラスの変数に代入することができる。
sample.java
import java.time.LocalDate;
public class Sample {
public static void main(String[] args) {
ChildHuman ch = new ChildHuman("mr.child", 10, "male", LocalDate.of(2000, 2, 4));
// スーパークラスに代入
ParentHuman ph = ch;
}
}
左右で型が異なるが、サブクラスからスーパークラスのへの代入であれば自動型変換される。
インスタンスを生成したときにインスタンスがヒープ領域のどこにあるのかという情報で参照が代入されるが、ChildHumanの参照からParentHumanの参照に自動変換されるイメージ。
スーパークラスの変数に代入するとスーパークラス型の範囲内でしか、インスタンスにアクセスできなくなる。
sample.java
import java.time.LocalDate;
public class Sample {
public static void main(String[] args) {
ChildHuman ch = new ChildHuman("mr.child", 10, "male", LocalDate.of(2000, 2, 4));
ParentHuman ph = ch;
System.out.println(ph.getName());
System.out.println(ph.getAge());
System.out.println(ph.getGender());
System.out.println(ph.getBirthday()); // コンパイルエラー
}
}
上記のようにParentHumanで定義されているゲッターにはアクセスできるが、ChildHumanのgetBirthdayにアクセスしようとするとコンパイルエラーが発生する。