Javaの参照型の型変換【アップキャストとダウンキャスト】

スポンサーリンク
この記事は約6分で読めます。

参照型の型変換

Javaでは、あるクラス型のオブジェクトを別のクラス型に変換することができるアップキャストとダウンキャストの2種類があります。

アップキャスト(Upcasting):自動型変換

アップキャストは、サブクラス型の変数をスーパークラス型(変数)の参照に代入できます。

アップキャストは自動的に行われ、明示的なキャストは不要です。

また、アクセスできる範囲は、スーパークラス部分に限定され、参照型の型により、アクセスできる範囲が決まります。

ダウンキャスト(Downcasting):明示的型変換

ダウンキャストは、インスタンス(実体)がサブクスの場合、スーパークラス型の変数をサブクラス型の変数に代入(変数)の参照に代入できます。

ダウンキャストは明示的にキャスト演算子()を使って行う必要があり、実行時に型チェックが行われます

また、アクセスできる範囲は、サブクラス全体で、参照型の型により、アクセスできる範囲が決まります。

キャストできるかどうか知りたいときは、「変数名 instanseof 型名」と書きます。
ダウンキャストが可能な場合 true で、そうでない場合は false です。

インスタンスの型

型変換ができるは、参照の型のみで、インスタンス(実体)の型は変わりません

ダイナミックバインディング

ダイナミックバインディング(Dynamic Binding)は、プログラムの実行時にメソッドの呼び出し先を決定する仕組みです。インタンス(実体)の型に従って、オーバーライドされたメソッドを決定します。

参照型の型変換を行った場合でも、オブジェクトの実際の型に基づいて適切なメソッドが呼び出されます。

サンプルコード:Animalクラス

/**
 * スーパークラス
 * @author chiraura
 */

class Animal {
	protected String name;

	/**
	 * メソッド
	 */

	public Animal(String name) {
		this.name = name;
	}

	public void makeSound() {
		System.out.println("動物の鳴き声");
	}
}
  • name フィールドと makeSound メソッドを持つ基本クラスです。
  • makeSound メソッドは一般的な動物の鳴き声を出します。

サンプルコード:Dogクラス

/**
 * サブクラス (Animalクラスを継承)
 * @author chiraura
 */

class Dog extends Animal {
	public Dog(String name) {
		super(name);
	}

	/**
	 * makeSound(オーバーライド)
	 */
	@Override
	public void makeSound() {
		System.out.println("ワン");
	}

	/**
	 * メソッド fetch
	 */

	public void fetch() {
		System.out.println(name + "餌を取ってきています。");
	}
  • Animal クラスを継承しています。
  • makeSound メソッドをオーバーライドして、犬の鳴き声を出します。
  • fetch メソッドを追加して、犬が物を取ってくる動作を表現します。

サンプルコード:Catクラス

/**
 * サブクラス (Animalクラスを継承) 
 * @author chiraura
 */
class Cat extends Animal {
	public Cat(String name) {
		super(name);
	}

	/**
	 * makeSound (オーバーライド)
	 */
	@Override
	public void makeSound() {
		System.out.println("ニャン");
	}
}
  • Animal クラスを継承しています。
  • makeSound メソッドをオーバーライドして、猫の鳴き声を出します。

サンプルコード:Mainクラス

/**
 * 実行用クラス
 * @author chiraura
 */
public class Main {
	public static void main(String[] args) {
		// サブクラスのインスタンス化・メソッド呼び出し
		Animal myDog = new Dog("レックス:"); // アップキャスト
		Animal myCat = new Cat("モモ:");     // アップキャスト

		myDog.makeSound();                    // 出力: ワン
		myCat.makeSound();                    // 出力: ニャン

		/**
		 * ダイナミックバインディング
		 */

		// ダウンキャストしてサブクラス固有のメソッドを呼び出す
		if (myDog instanceof Dog) {
			Dog dog = (Dog) myDog;
			dog.fetch();                   // 出力: 取ってきています
		}

		if (myCat instanceof Cat) {
			Cat cat = (Cat) myCat;
			cat.makeSound();               // 出力: ニャン
		}
	}
}
  • Animal 型の変数に Dog オブジェクトと Cat オブジェクトを代入します(アップキャスト)。
  • makeSound メソッドを呼び出すと、実際のオブジェクトの型に基づいて適切なメソッドが実行されます(ダイナミックバインディング)。
  • instanceof 演算子を使ってオブジェクトの実際の型を確認し、適切なダウンキャストを行います。
  • ダウンキャスト後に Dog クラスの fetch メソッドを呼び出します。

実行結果

ワン
ニャン
レックス:餌を取ってきています
ニャン

ダイナミックバインディングの重要性

  • 柔軟性の向上: ダイナミックバインディングを利用することで、同じスーパークラス型の変数で異なるサブクラスのオブジェクトを操作でき、コードの柔軟性が向上します。
  • 拡張性の向上: 新しいサブクラスを追加する際に、既存のコードを変更せずに拡張できるため、システムの拡張性が向上します。
  • 再利用性の向上: スーパークラスに共通の操作をまとめ、サブクラスで具体的な実装を行うことで、コードの再利用性が向上します。

まとめ

ダイナミックバインディングは、オブジェクト指向プログラミングにおいて非常に重要な概念です。参照型の型変換と組み合わせることで、柔軟で拡張性のあるコードを書くことができます。適切に利用することで、システムの設計と実装がより効率的かつ保守しやすくなります。

にほんブログ村 IT技術ブログ IT技術メモへ

コメント

タイトルとURLをコピーしました