ねっとぱんだ-プログラミング勉強ブログ-

Webデザイン、プログラミングの勉強ブログ。

【java】アップキャスト、ダウンキャスト

アップキャスト

サブクラスからスーパークラスへと型が変換されること

サブクラス(継承先のクラス)をスーパークラス(継承元のクラス)の参照型オブジェクトに代入した時、自動的にアップキャストが行われる。

↓参照型オブジェクト等の名称の復習

//左辺 参照型オブジェクト
//右辺 インスタンス
ClassName a = new ClassName();

/*
インスタンス化する際の左辺をスーパークラス、右辺をすでにインスタンス化してあるサブクラスにして記述した時、アップキャストが行われる。
*/

SubClassのインスタンスをSuperClassへアップキャストしている。

class SuperClass{
	public void method1(){
		System.out.println("スーパークラスのメソッド");
	}
}

class SubClass extends SuperClass {
	public void method2(){
		System.out.println("サブクラスのメソッド");
	}
}

public class practice{
	public static void main(String[] args){
    
        //サブクラスをインスタンス化
		SubClass sb = new SubClass();
		
		//サブクラスはSubClassとSuperClassのメソッドを両方使える
		sb.method1();
		sb.method2();
		
		/*
        Subclassのインスタンスを
		SuperClassの参照オブジェクトに代入
        ここでアップキャストが行われている
        */
		SuperClass sp = new SuperClass();
		
        /*
        スーパークラスに型変換された為、
        サブクラスのメソッドは使えない
        */
		sp.method1();
		//sp.method2();
	}
}

注意

アップキャストが行われた時、
同じ名前のフィールドとメソッドがあった場合
フィールドはスーパークラスメソッドはサブクラス
が優先される。

class SuperClass{
	int i = 1;
	public String method(){
		return "スーパークラスのメソッド" + (i * 5) ;
	}
}

class SubClass extends SuperClass {
	int i = 2;
	public String method(){
		return "サブクラスのメソッド"  + (i * 10);
	}
}

public class practice{
	public static void main(String[] args){
		SubClass sb = new SubClass();
		
		//サブクラスのフィールドiが呼び出される
		System.out.println("i = " + sb.i);
		//サブクラスのメソッドが呼び出される
		System.out.println(sb.method());
		
		/*Subclassのインスタンスを
		SuperClassの参照オブジェクトに代入*/
		SuperClass sp = sb;
		
		//スーパークラスのフィールドiが呼び出される
		System.out.println("i = " + sp.i);
		//サブクラスのメソッドが呼び出される
		System.out.println(sp.method());
	}

結果は以下になる。

i = 2
サブクラスのメソッド20
i = 1
サブクラスのメソッド20

フィールドiの値はそれぞれ違うクラスから呼び出されているが、メソッドは両方ともサブクラスのメソッド優先され、2 * 10の結果が表示されている。

メソッド内のフィールド i はサブクラスの値の為、
メソッドが呼び出すフィールドもサブクラスが優先される(?)

ダウンキャスト

  • 型をサブクラスに戻せる(?)
  • アップキャストした参照型オブジェクトのみダウンキャスト可能
  • 通常のキャストのように明示的に記述しなければいけない↓

(クラス名)オブジェクト名

public class practice{
	public static void main(String[] args){
		SubClass sb = new SubClass();
		
		/*アップキャスト*/
		SuperClass sp = sb;
		
		/*ダウンキャスト*/
		SubClass sb2 = (SubClass)sp;
		
		System.out.println(sb2.i);
		System.out.println(sb2.method());
	}
}

上記の結果は以下

2
サブクラスのメソッド20

フィールドiはサブクラスが呼ばれ
メソッドもサブクラスのものになっている。

注意

アップキャストしていないクラスをダウンキャストすると実行段階でエラーになる。

        //普通にインスタンス化
        SuperClass sp = new SuperClass();
		
		//ダウンキャスト
		SubClass sb2 = (SubClass)sp;

↓結果

Exception in thread "main" java.lang.ClassCastException: SuperClass cannot be cast to SubClass
at practice.main(practice.java:24)

その他

なぜアップキャストは安全で、ダウンキャストは危険なのか
http://qiita.com/RYO-4947123/items/eaeb48b6fcf97c02710f