Javaの親子クラス/インターフェース間の代入のサンプルです。
目次
サンプル | 子クラスから親クラスの型への代入 |
親クラスから子クラスの型への代入 | |
クラスからインターフェースの型への代入 |
子クラスから親クラスの型への代入
子クラスから親クラスの型の変数への代入は、暗黙的に型変換が行われるのでそのまま代入できます。
package test1;
class Machine1 {
void print1() {
System.out.println("RED");
}
}
class Machine2 extends Machine1 {
void print2() {
System.out.println("BLUE");
}
}
public class Test1 {
public static void main(String[] args) {
Machine2 mc2 = new Machine2(); //子クラスのデータ型に代入
Machine1 mc1 = mc2; //親クラスのデータ型に代入
mc1.print1(); //RED
//mc1.print2(); //コンパイルエラ-
}
}
16行目のmc2のインスタンスイメージです。子クラスのインスタンス化に伴い親クラスもインスタ化されています。
18行目は、親クラスの型の変数に代入しています。キャストなしで実行できます。
子クラスは親クラスのメンバーを保持しているためです。
変数の型で実行できるメソッドが制限
18行目のmc1のインスタンスイメージです。親クラスのデータ型のため、親クラスにあるメソッドのみ実行できます。
20行目は、子クラスのメソッドを実行しようとしていますがコンパイルエラーになります。
オーバーライドは実行される
9行目のメソッドをprint1に変更した場合、19行目は子クラスのメソッドが実行されBLUEが出力されます。オーバーライドは実行されます。
親クラスから子クラスの型への代入
親クラスから子クラスの型の変数への代入は、明示的にダウンキャストを行う必要があります。
package test1;
class Machine1 {
void print1() {
System.out.println("RED");
}
}
class Machine2 extends Machine1 {
void print2() {
System.out.println("BLUE");
}
}
public class Test1 {
public static void main(String[] args) {
Machine1 mc1 = new Machine2(); //親クラスのデータ型に代入
mc1.print1(); //RED
// mc1.print2(); //コンパイルエラー
Machine2 mc2 = (Machine2)mc1; //子クラスのデータ型に代入
mc2.print1(); //RED
mc2.print2(); //BLUE
}
}
17行目のmc1のインスタンスイメージです。子クラスのインスタンス化に伴い親クラスもインスタ化されていますが、データ型が親クラスのため、親クラスのメソッドしか使用できません。
20行目は、子クラスの型の変数にダウンキャストを行って代入しています。ダウンキャストしない場合コンパイルエラーになります。
親クラスは子クラスのすべてのメンバーを保持しているとは限らないためです。キャストは、データ型をかっこで括ります。
データ型が子クラスのため、子クラスのメソッドも使用できます。
クラスからインターフェースの型への代入
クラスからインターフェースの型の変数への代入は、暗黙的に型変換が行われるのでそのまま代入できます。
package test1;
interface Machine1 {
void print1();
}
class Machine2 implements Machine1 {
public void print1() {
System.out.println("RED");
}
public void print2() {
System.out.println("BLUE");
}
}
public class Test1 {
public static void main(String[] args) {
Machine2 mc2 = new Machine2(); //クラスのデータ型に代入
Machine1 mc1 = mc2; //インターフェースのデータ型に代入
mc1.print1(); //RED
// mc1.print2(); //コンパイルエラー
}
}
17行目のmc2のインスタンスイメージです。2つのメソッドがあります。
19行目は、インターフェース型の変数に代入しています。キャストなしで実行できます。
インターフェースを実装しているクラスはインターフェースのすべてのメンバーを保持しているためです。
データ型がインターフェースのため、インターフェースにないメソッドは参照不可になります。
関連の記事