Java でコンストラクターをオーバーロードする

Mohammad Irfan 2023年10月12日
  1. Java のデフォルトコンストラクタ
  2. Java のパラメーター化されたコンストラクター
  3. コンストラクターのオーバーロードのないコード
  4. Java でのコンストラクターのオーバーロード
  5. コンストラクターのオーバーロードのベストプラクティス
  6. コンストラクターをオーバーロードする
Java でコンストラクターをオーバーロードする

このチュートリアルでは、Java でコンストラクターをオーバーロードする方法を紹介します。また、このトピックをよりよく理解するために従うことができるいくつかのサンプルコードをリストしました。

コンストラクターは、クラスオブジェクトにメモリを割り当て、そのオブジェクトのクラス属性を初期化するために呼び出されるメソッドです。クラスのコンストラクターが作成されていない場合、Java はデフォルトのコンストラクターを提供します。

たとえば、以下のクラスではコンストラクターが定義されていません。それでも、属性がデフォルト値(この場合は null)に初期化されている間に、そのクラスのオブジェクトを作成できます。

Java のデフォルトコンストラクタ

class Student {
  String name;
  Double gpa;
}
public class Main {
  public static void main(String[] args) {
    Student s = new Student();
    System.out.println(s.name + "\t" + s.gpa);
  }
}

出力:

null	null

コンストラクターのオーバーロードの概念は、メソッドのオーバーロードに似ています。つまり、1つのクラスに複数のコンストラクターがあります。コンストラクターのオーバーロードは、さまざまな方法でクラスのメンバー変数を初期化するために行われます。

オーバーロードされたコンストラクターは必要な数だけ作成できます。唯一の条件は、オーバーロードされたコンストラクターは、それらが取るパラメーターの数とタイプが異なる必要があるということです。

たとえば、以下に示す Student クラスで、student nameGPA の 2つの属性があるとします。クラスにはコンストラクターが定義されています。コンストラクターは、パラメーターとして文字列名と二重の GPA を取り、新しいオブジェクトの対応する属性を初期化します。

Java のパラメーター化されたコンストラクター

class Student {
  String name;
  Double gpa;
  Student(String s, Double g) {
    name = s;
    gpa = g;
  }
}
public class Main {
  public static void main(String[] args) {
    Student s = new Student("Justin", 9.75);
    System.out.println(s.name + "\t" + s.gpa);
  }
}

出力:

Justin	9.75

コンストラクターのオーバーロードのないコード

新しいオブジェクトを作成するときに、学生名のみがコンストラクターに渡されるシナリオを考えてみます。この場合、GPA は自動的に null に設定されます。コンストラクターをオーバーロードせずに名前を渡すだけの場合、次のコンパイルエラーが発生します。

class Student {
  String name;
  Double gpa;
  Student(String s, Double g) {
    name = s;
    gpa = g;
  }
}
public class Main {
  public static void main(String[] args) {
    Student s = new Student("Justin");
    System.out.println(s.name + "\t" + s.gpa);
  }
}

出力:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The constructor Student(String) is undefined

	at ConstructorOverloading.main(ConstructorOverloading.java:18)

Java でのコンストラクターのオーバーロード

上記の状況に対処するためのパラメーターとして、学生名のみを使用してオーバーロードされたコンストラクターを作成できます。このコンストラクターが呼び出されたときに、GPAnull に設定します。

class Student {
  String name;
  Double gpa;
  Student(String s, Double g) {
    name = s;
    this.gpa = g;
  }
  Student(String s) {
    name = s;
    gpa = null; // Setting GPA to null
  }
}
public class Main {
  public static void main(String[] args) {
    Student s1 = new Student("Justin");
    Student s2 = new Student("Jessica", 9.23);
    System.out.println(s1.name + "\t" + s1.gpa);
    System.out.println(s2.name + "\t" + s2.gpa);
  }
}

出力:

Justin	null
Jessica	9.23

Student オブジェクトが作成されたが、名前も GPA も言及されていない別の状況を考えてみます。引数をとらず(デフォルトのコンストラクター)、name および GPA 属性を null に設定する別のオーバーロードされたコンストラクターを作成できます。

Java は、クラスに対して他のコンストラクターが作成されていない場合にのみ、デフォルトのコンストラクターを提供することに注意してください。ただし、このクラスの場合、コンストラクターは既に存在するため、デフォルトのコンストラクターを作成する必要があります。

class Student {
  String name;
  Double gpa;
  Student(String s, Double g) {
    name = s;
    gpa = g;
  }
  Student(String s) {
    name = s;
    gpa = null;
  }
  Student() {
    name = null;
    gpa = null;
  }
}
public class Main {
  public static void main(String[] args) {
    Student s1 = new Student();
    Student s2 = new Student("Justin");
    Student s3 = new Student("Jessica", 9.23);
    System.out.println(s1.name + "\t" + s1.gpa);
    System.out.println(s2.name + "\t" + s2.gpa);
    System.out.println(s3.name + "\t" + s3.gpa);
  }
}

出力:

null	null
Justin	null
Jessica	9.23

コンストラクターのオーバーロードのベストプラクティス

コンストラクターをオーバーロードするときに従うべき決まったガイドラインはありません。ただし、混乱を避け、エラーの範囲を減らすために従うことができる推奨されるベストプラクティスがいくつかあります。

  • クラスのメンバー変数を参照するには、this キーワードを使用する必要があります。混乱を避け、コードを読みやすくします。
  • より直感的なパラメーター名をコンストラクターに渡すこともできます。たとえば、コンストラクターが名前フィールドを初期化する場合、コンストラクターの署名は Student(String s) ではなく Student(String name) になります。this キーワードを使用すると、name と呼ばれるパラメーターと、name とも呼ばれるクラス属性を区別できます。

Student クラスの例を続けて、コンストラクター内で this キーワードを使用しましょう。

class Student {
  String name;
  Double gpa;
  Student(String name, Double gpa) // passing more intuitive parameter names
  {
    this.name = name; // using this keyword to avoid confusion
    this.gpa = gpa;
  }
  Student(String name) {
    this.name = name;
    this.gpa = null;

    Student()

        this.name = null;
    this.gpa = null;
  }
}
  • クラスが単一のプライマリコンストラクタのみを持つこともお勧めします。残りのすべてのコンストラクタは、このプライマリコンストラクタを呼び出して属性を初期化する必要があります。
  • this() 関数を使用して、別のコンストラクターからコンストラクターを呼び出すことができます。this() に渡す属性の数とタイプによって、呼び出されるコンストラクターが決まります。
  • コードの冗長性が減り、単一のコンストラクターのロジックを記述するだけで済みます。
  • Student クラスでは、3つのオーバーロードされたコンストラクターが必要です。主要なコンストラクターは、パラメーターとして nameGPA の両方をとるパラメーター化されたコンストラクターになります。他の 2つのオーバーロードされたコンストラクターは、単にプライマリコンストラクターを呼び出し、パラメーターの値を null として渡します。
class Student {
  String name;
  Double gpa;
  Student(String name, Double gpa) // Primary Constructor that sets the attribute values
  {
    this.name = name;
    this.gpa = gpa;
  }
  Student(String name) {
    this(name, null); // Calling the primary constructor with GPA as null
  }
  Student() {
    this(null, null); // Calling the primary constructor with both parameters as null
  }
}

コンストラクターをオーバーロードする

コンストラクターのオーバーロードは、さまざまな方法でクラスの属性を初期化するために行われます。オーバーロードされたコンストラクターは、パラメーターの数、またはそれらに渡されるパラメーターのデータ型が異なる必要があります。

各コンストラクターの署名は、他のコンストラクターとは異なる必要があります。this キーワードを使用して、クラス属性やその他のコンストラクターを参照する必要があります。これにより、コードの冗長性が減り、理解しやすくなります。

関連記事 - Java Constructor