まず第一に、スーパークラスの型にサブクラスの型を入れているわけではなく
スーパークラスの型の変数にサブクラスのオブジェクトを入れています。
端的に利点だけを挙げます
Dogクラスのほかに、Cat、FishクラスなどAnimalクラスを継承したものをたくさん作った場合、オブジェクト生成する時にいちいち固有の型の変数に入れるのはとても面倒です。
そこで、作ったオブジェクトをすべてAnimal型とみなします
以下は例です
Animal.java
public class Animal{
String name;
int age;
String gender;
Animal(String name, int age, String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public void info(){
System.out.println("名前:" + name + "\n年齢:" + age + "\n性別:" + gender);
}
public void run(){
System.out.println(name + "は走ります");
}
}
Dog.java
public class Dog extends Animal{
Dog(String name, int age, String gender){
super(name, age, gender);
}
}
Cat.java
public class Cat extends Animal{
Cat(String name, int age, String gender){
super(name, age, gender);
}
}
Fish.java
public class Fish extends Animal{
Fish(String name, int age, String gender){
super(name, age, gender);
}
//魚は走れないのでオーバーライド、run()メソッドを固有の処理に変えます
public void run(){
System.out.println(name + "は泳ぎます");
}
}
MainClass.java
public class MainClass{
public static void main(String[] args){
//Dog, Cat, Fishクラスのオブジェクトを作り、それらをAnimal型配列に格納
Animal[] animals = {
new Dog("ポチ",7,"オス"),
new Cat("タマ",9,"メス"),
new Fish("魚",2,"不明")
};
//全て型がAnimal型なのでForEach文で繰り返せる!
for(Animal animal : animals){
animal.info();
animal.run();
System.out.println();
}
}
}
名前:ポチ
年齢:7
性別:オス
ポチは走ります
名前:タマ
年齢:9
性別:メス
タマは走ります
名前:魚
年齢:2
性別:不明
魚は泳ぎます
あくまでこれは利点の一つです。
サブクラス達をスーパークラスの型の変数に格納すれば、このようにforEachでAnimal型とみなして取り扱うことが出来ます。
もしこうしない場合は、いちいちDog型の変数、Cat型の変数、Fish型の変数を用意してやる必要があり、とても面倒です。
難しい言葉を使うと、これらはポリモーフィズムという考え方につながります