// 抽象クラス Shape
abstract class Shape {
// 抽象メソッド calculateArea
public abstract double calculateArea();
}
// Circle クラス
class Circle extends Shape {
// メンバー変数
private double radius;
// コンストラクタ
public Circle(double radius) {
this.radius = radius;
}
// calculateArea メソッドのオーバーライド
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
// Rectangle クラス
class Rectangle extends Shape {
// メンバー変数
private double width;
private double height;
// コンストラクタ
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
// calculateArea メソッドのオーバーライド
@Override
public double calculateArea() {
return width * height;
}
}
// Main クラス
public class Main {
public static void main(String[] args) {
// 異なる形状のインスタンスを作成
Circle circle = new Circle(5.0);
Rectangle rectangle = new Rectangle(4.0, 6.0);
// 各形状の面積を計算して表示
System.out.println("Circle Area: " + circle.calculateArea());
System.out.println("Rectangle Area: " + rectangle.calculateArea());
}
}
このプログラムでは、Shape クラスを抽象クラスとして定義し、Circle クラスと Rectangle クラスがそれを継承して calculateArea メソッドをオーバーライドしています。Main クラスでは、異なる形状のインスタンスを作成し、それぞれの面積を計算して表示しています。
ポリモーフィズムの応用
- メソッドのオーバーライド:
- ポリモーフィズムでは、親クラスで宣言されたメソッドをサブクラスで同じメソッド名で再定義することができます。これをメソッドのオーバーライドと呼びます。
- インターフェースを実装するクラスや、抽象クラスを継承するサブクラスでは、共通のメソッド名を使用することで、同じメソッド呼び出しで異なる実装を実現します。
- 多態性:
- ポリモーフィズムにより、同じ型を持つ複数のオブジェクトが異なる振る舞いをすることがあります。これは多態性と呼ばれ、プログラムの柔軟性を高めます。
- 例えば、同じインターフェースを実装した複数のクラスがある場合、それぞれのオブジェクトを同じ型として扱いながら、実際には各オブジェクトに応じた動作が可能です。
- ジェネリックプログラミング:
- ポリモーフィズムはジェネリックプログラミングにも関連しています。ジェネリック型を使用することで、特定の型に依存せずに、汎用的なクラスやメソッドを実装できます。
- ジェネリック型を使用することで、様々な型に対して同じ操作を行うことができ、コードの再利用性が向上します。
- 動的なメソッドの呼び出し:
- ポリモーフィズムにより、実行時にオブジェクトの実際の型に基づいて動的にメソッドを呼び出すことができます。これを動的ディスパッチと呼びます。
- インターフェースや抽象クラスを使用することで、プログラムが柔軟に変更される場合にも、コードの変更が最小限に抑えられます。
- ポリモーフィックなコレクション:
- ポリモーフィズムは、コレクション内に異なる型のオブジェクトを格納する際にも利用されます。共通の親クラスやインターフェースを指定することで、異なる型を同じコレクションにまとめて管理できます。
ポリモーフィズムを適切に使用することで、コードの柔軟性や再利用性が向上し、保守性の高いプログラムを実現できます。ただし、ポリモーフィズムを効果的に利用するためには、オブジェクト指向の基本概念に対する理解が欠かせません。