Javaで抽象クラスのインスタンスは生成できる?参照変数の正しい使い方を解説
結論から言うと、抽象クラス(abstract class)のオブジェクト(インスタンス)を直接生成することはできません。ただし、抽象クラス型の参照変数を作成することは可能です。この参照変数は、抽象クラスを継承した派生クラス(サブクラス)のオブジェクトを参照するために使われます。
抽象クラスとは何か
抽象クラスとは、実装の詳細を隠蔽し、機能の定義だけをユーザーに見せるための仕組みです。Javaの抽象クラスには、デフォルトの動作を実装したインスタンスメソッドを持たせることもできます。
設計段階である程度の実装が確定していて、かつ一部の処理をサブクラスに委ねたい場合に、抽象クラスを選択するのが適切です。
サンプルコード
以下の例では、抽象クラス Diagram を定義し、それを継承する Rectangle(長方形)と Triangle(三角形)の2つの具象クラスを作成しています。
abstract class Diagram {
double dim1;
double dim2;
Diagram(double a, double b) {
dim1 = a;
dim2 = b;
}
// area() は抽象メソッド
abstract double area();
}
class Rectangle extends Diagram {
Rectangle(double a, double b) {
super(a, b);
}
// 長方形用に area() をオーバーライド
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Diagram {
Triangle(double a, double b) {
super(a, b);
}
// 三角形用に area() をオーバーライド
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
public class Test {
public static void main(String args[]) {
// Diagram d = new Diagram(10, 10); // 抽象クラスなのでコンパイルエラー
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Diagram diagRef; // これはOK。オブジェクトは生成されない
diagRef = r;
System.out.println("Area of Rectangle is: " + diagRef.area());
diagRef = t;
System.out.println("Area of Triangle is:" + diagRef.area());
}
}このコードのポイントは次のとおりです。
new Diagram(10, 10)のように抽象クラスを直接インスタンス化しようとすると、コンパイルエラーになります。- 一方、
Diagram diagRef;のように参照変数の宣言は問題なく行えます。この時点ではオブジェクトは生成されていません。 - 宣言した
Diagram型の参照変数diagRefには、サブクラスであるRectangleやTriangleのオブジェクトを代入できます。
参照変数 diagRef に Rectangle のオブジェクトを代入すれば長方形の面積計算が、Triangle のオブジェクトを代入すれば三角形の面積計算が、それぞれポリモーフィズムによって適切に実行されます。
実行結果
Inside Area for Rectangle. Area of Rectangle is: 45.0 Inside Area for Triangle. Area of Triangle is:40.0
まとめ
- 抽象クラスは
newによる直接のインスタンス化ができない。 - 抽象クラス型の参照変数は作成でき、サブクラスのオブジェクトを参照できる。
- これにより、共通のインターフェースを保ちながら、サブクラスごとの具体的な処理を実現できる。
抽象クラスと参照変数を組み合わせることで、柔軟で拡張性の高いオブジェクト指向設計が可能になります。
-
Javaの列挙型(enum)は任意のクラスを拡張できる?継承の仕組みを解説
Javaの列挙型(enum)とは列挙型(enum)は、Javaにおいて定数の集合を格納するためのデータ型です。1週間の曜日や1年の月名など、固定された値のグループを扱う際に活用されます。列挙型を定義するには、enumキーワードの後に列挙型の名前を続けて記述します。enum Days { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }配列と同様に、列挙型内の要素(定数)には0から始まる番号が自動的に割り当てられます。上記の例では、各曜日が以下の図のように番号で識別されます。列挙型はクラスとよく似た構造を持ち
-
JSONスキーマからPythonクラスを自動生成する方法【python-jsonschema-objects活用ガイド】
JSONオブジェクトからPythonクラスを作成するには?JSONデータをPythonで扱う際、辞書型のまま操作すると属性アクセスができず、コードの可読性が低下しがちです。そんなときに便利なのが python-jsonschema-objects というライブラリです。このライブラリは、広く使われている jsonschema を基盤として構築されており、JSONスキーマから自動的にクラスベースのバインディング(クラス定義)を生成し、Python上でオブジェクトのように直感的に扱えるようにしてくれます。この記事では、サンプルのJSONスキーマを使って、実際にPythonクラスを生成し、値の検証ま