🙈

【Java】Polymorphism(多態性)について

2021/09/21に公開

この記事でわかること

  • Polymorphism(ポリモーフィズム・多態性)について
  • オーバーライドについて
  • オーバーロードについて

Polymorphism(多態性)とは

同一の命令(メッセージ)に対して、それを受け取った側が、自分自身のクラスに記述されている命令(メソッド)に従って、独自の動作を振る舞いを見せること

オーバーライドで表現するPolymorphism

オーバーライドとは

スーパークラス定義されたメソッドをサブクラスで再定義することで、固有の処理に書き換えること。あるメソッドをオーバーライドするにはスーパークラスのメソッドと同じメソッドをサブクラスに宣言する。(同一のシグニチャである必要がある)

オーバーライドの具体例(:java)

class Superclass {
	String text;

	void setText(String text) {
		this.text = text;
	}

	void callText() {
		System.out.println("superclassのメソッドから呼ばれたテキスト: " + text);
	}
}

class Subclass1 extends Superclass {
	// @Overrideは省略可能だが明示しておくことでスペルミスなどによるコンパイラエラーにも対応できる
	@Override
	void callText() {
		System.out.println("subclass1のメソッドから呼ばれたテキスト: " + text);
	}
}

class Subclass1 extends Superclass {
	// @Overrideは省略可能だが明示しておくことでスペルミスなどによるコンパイラエラーにも対応できる
	@Override
	void callText() {
		System.out.println("subclass2のメソッドから呼ばれたテキスト: " + text);
	}
}

// 呼び出し確認

Superclass super1 = new Superclass();
super1.setText("Hello, World");
super1.callText();
// => superclassのメソッドから呼ばれたテキスト: Hello, World

Subclass1 sub1 = new Subclass1();
sub1.setText("Hello, World");
sub1.callText();
// => subclass1のメソッドから呼ばれたテキスト: Hello, World

Subclass2 sub2 = new Subclass2();
sub2.setText("Hello, World");
sub2.callText();
// => subclass2のメソッドから呼ばれたテキスト: Hello, World

SuperclassのcallTextメソッドを各サブクラスで再定義し、処理を変えている

final修飾子によるオーバライドの禁止

継承先でメソッドのオーバーライドを出来ないように、スーパークラスでfinal修飾子を付与したメソッドを定義することでオーバーライドを禁止する方法がある。

具体例(:java)

class Superclass {
	String text;

	void setText(String text) {
		this.text = text;
	}
  // final修飾子を付け加えてオーバーライドを出来なくする
	final void callText() {
		System.out.println("superclassのメソッドから呼ばれたテキスト: " + text);
	}
}

class Subclass1 extends Superclass {
	// コンパイルエラー
  // overridden method is final
	@Override
	void callText() {
		System.out.println("subclass1のメソッドから呼ばれたテキスト: " + text);
	}
}

オーバーロードで表現するPolymorphism

オーバーロードとは

同一クラス内にて、同じメソッド名で異なるシグニチャを複数定義すること。

オーバーロードの具体例(:java)

class Test {
	String text;

	void setText(String text) {
		this.text = text;
	}

	void callText(String text) {
		System.out.println("superclassのメソッドから呼ばれたテキスト: " + text);
	}

	void callText() {
		System.out.println("superclassのメソッドから呼ばれたテキスト: " + text);
	}
}

// 呼び出し確認

Test test = new Test();
test.setText("Hello, World");

test.callText();
// => Hello, World

test.callText("Hello, Java");
// => Hello, Java

シグニチャとは

メソッド名と引数のこと

// callText(String text)までをシグニチャと呼ぶ
void callText(String text) {
}

まとめ

Polymorphism(多態性)を利用することで、呼び出し側はメッセージ(メソッド)を同一のものとみなし、一度の呼び出し(記述)だけでいいのに対して、呼び出される側(メソッド)は自分自身で決められた動作をしてくれるので、プログラムコードの重複を防ぐことや可読性を上げることができるようになります。

Discussion