Javaで抽象クラスにはコンストラクターがあるのに、インターフェースにコンストラクターがない理由を解説
コンストラクターとは、オブジェクトに対応して特定のクラスの非静的(non-static)メンバーを初期化するための仕組みです。本記事では、なぜJavaにおいて抽象クラスにはコンストラクターが存在する一方、インターフェースにはコンストラクターが存在しないのかを、具体例とともにわかりやすく解説します。
インターフェースにコンストラクターがない理由
- Javaのインターフェースにはコンストラクターがありません。その理由は、インターフェースのすべてのデータメンバーがデフォルトで public static final、つまり定数として扱われるためです。定数は宣言時に値を代入する必要があります。
- インターフェースにはコンストラクターによって初期化すべきインスタンスデータメンバーが存在しません。
- メソッドを呼び出すにはオブジェクトが必要ですが、インターフェースのメソッドは本体(実装)を持たないため、インターフェースのメソッドを直接呼び出す必要はありません。
- インターフェースのメソッドを呼び出せない以上、インターフェースのオブジェクトを生成する必要もなく、したがってコンストラクターを持つ必要性もないのです。
例1:インターフェースの実装
interface Addition {
int add(int i, int j);
}
public class Test implements Addition {
public int add(int i, int j) {
int k = i + j;
return k;
}
public static void main(String args[]) {
Test t = new Test();
System.out.println("k value is:" + t.add(10, 20));
}
}
出力結果
k value is:30
この例では、Addition インターフェースを実装した Test クラスのオブジェクトを生成してメソッドを呼び出しています。オブジェクトが生成されるのはあくまで実装クラスであり、インターフェース自体はインスタンス化されません。
抽象クラスにおけるコンストラクターの役割
- クラスにおけるコンストラクターの目的は、フィールドを初期化することであり、オブジェクトそのものを構築することではありません。
- 抽象スーパークラスの新しいインスタンスを直接生成しようとすると、コンパイラーはエラーを出します。
- しかし、抽象クラスを継承したサブクラスからは、スーパークラスのコンストラクターを利用して変数を設定することが可能です。
つまり、抽象クラスは直接インスタンス化できないものの、サブクラスのオブジェクト生成時に super() を通じてコンストラクターが呼び出され、継承されたフィールドを適切に初期化できるのです。これが抽象クラスにコンストラクターが必要とされる理由です。
例2:抽象クラスのコンストラクターの利用
abstract class Employee {
public String empName;
abstract double calcSalary();
Employee(String name) {
this.empName = name; // 抽象クラスのコンストラクター
}
}
class Manager extends Employee {
Manager(String name) {
super(name); // サブクラスのコンストラクターで名前を設定
}
double calcSalary() {
return 50000;
}
}
public class Test {
public static void main(String args[]) {
Employee e = new Manager("Adithya");
System.out.println("Manager Name is:" + e.empName);
System.out.println("Salary is:" + e.calcSalary());
}
}
出力結果
Manager Name is:Adithya Salary is:50000.0
この例では、抽象クラス Employee のコンストラクターが従業員名を初期化し、サブクラス Manager のコンストラクター内で super(name) を呼び出すことでその値を設定しています。new Manager("Adithya") によってオブジェクトを生成すると、自動的に抽象クラス側のコンストラクターも実行される仕組みです。
まとめ
インターフェースは状態(インスタンスフィールド)を持たず、実装を持たない契約(コントラクト)としての役割しかないため、初期化処理を行うコンストラクターが不要です。一方、抽象クラスはフィールドや部分的な実装を持つことができ、サブクラスから継承される際にそれらを初期化する必要があるため、コンストラクターが用意されています。この違いを理解することで、Javaのオブジェクト指向設計における両者の役割の違いがより明確になるでしょう。
-
Javaの抽象クラスとは?基本ルールと実装例をわかりやすく解説
Javaの抽象クラスとは宣言に「abstract」キーワードを含むクラスは、抽象クラスと呼ばれます。抽象クラスは、継承によって利用されることを前提とした設計用のクラスであり、オブジェクト指向プログラミングにおける重要な概念の一つです。抽象クラスの主な特徴抽象クラスには、抽象メソッド(本体を持たないメソッド。例:public void get();)が含まれる場合もあれば、含まれない場合もあります。ただし、クラス内に1つでも抽象メソッドが存在する場合、そのクラスは必ず abstract として宣言しなければなりません。abstract として宣言されたクラスは、インスタンス化(newによるオブジ
-
Javaでコンストラクターにfinalを付けられない理由を解説
finalキーワードの役割とは Javaにおけるfinalキーワードは、メソッドがサブクラスでオーバーライドされることを防ぐために使用されます。finalが付いたメソッドは、たとえ継承関係にあっても子クラス側で再定義することはできません。 コンストラクターはオーバーライドできない 一方、コンストラクターはそもそもオーバーライドの対象になりません。その理由は、コンストラクターが継承されないためです。 サブクラスはスーパークラスのコンストラクターを受け継ぐことができず、必ず独自のコンストラクターを定義します。オーバーライドという概念自体が成立しない以上、それを禁止するためのfinalを付ける意味