[Java] 생성자(Constructor)

artp·2025년 2월 28일

java

목록 보기
19/32
post-thumbnail

생성자(Constructor)

자바에서 생성자는 객체가 생성될 때 자동으로 호출되는 특별한 메서드로, 객체의 필드를 초기화하는 역할을 합니다. 하지만 생성자가 객체를 생성하는 것은 아니며, 객체 생성은 new 키워드에 의해 이루어집니다.
또한, 상속 관계에서는 자식 클래스의 생성자를 호출하면 부모 클래스의 생성자가 자동으로 호출되는데, 이는 부모 클래스의 필드를 자식 객체 내부에서 올바르게 초기화하기 위함입니다.

1. 생성자의 정의와 역할

(1) 생성자의 정의

  • 생성자(Constructor)란, 클래스의 객체가 생성될 때 자동으로 호출되는 특별한 메서드입니다.
  • 클래스 이름과 동일한 이름을 가지며, 반환형이 없습니다.
  • 객체의 초기 상태를 설정(필드 초기화)하는 역할을 합니다.
  • 객체 생성 시 반드시 한 번 호출되며, 여러 번 호출될 수 없습니다.

(2) 생성자의 역할

  • 객체의 필드를 초기화하여 사용할 준비를 합니다.
  • 메모리에 객체가 생성될 때 자동으로 호출되며, 개발자가 직접 호출할 수 없습니다.
  • 생성자 호출이 객체 생성을 의미하지 않음.
    • 객체 생성은 new 키워드가 수행하며, 생성자는 생성된 객체의 필드를 초기화하는 역할만 합니다.
    • 즉, 생성자는 "새로운 변수를 만드는 것"이 아니라 "이미 존재하는 필드에 값을 설정하는 역할"을 합니다.
  • 생성자는 객체의 필드를 초기화하는 것이 주된 역할이므로, 필드 초기화가 없다면 생성자는 필요하지 않을 수도 있습니다.

2. 생성자의 특징과 규칙

  • 생성자는 반환형이 없다. (void조차 사용하지 않음)
  • 생성자는 new 키워드와 함께 사용되며, 객체를 초기화하는 역할을 한다.
  • 생성자는 오버로딩이 가능하다. (매개변수 개수나 타입을 다르게 하여 여러 개 선언 가능)
  • 생성자는 상속되지 않는다. (하지만 super()를 이용하여 부모 생성자를 호출 가능)
  • 클래스에 생성자를 명시하지 않으면, 자바 컴파일러가 자동으로 기본 생성자를 추가한다. (매개변수가 없는 public 클래스명() {} 형태)

기본 생성자(Default Constructor)

클래스에 생성자가 하나도 정의되지 않으면, 컴파일러가 자동으로 기본 생성자를 추가합니다.

class Example {
    // 생성자가 없으므로 기본 생성자가 자동 추가됨
}

public class Main {
    public static void main(String[] args) {
        Example ex = new Example(); // 자동으로 기본 생성자 호출
    }
}
  • 기본 생성자는 아무 동작도 하지 않으며, 단순히 객체를 생성합니다.
  • 하지만 생성자가 하나라도 정의되어 있다면, 기본 생성자는 자동 추가되지 않습니다.

3. 생성자 오버로딩 (Overloading)

같은 클래스 내에서 매개변수 개수 또는 타입이 다른 여러 개의 생성자를 정의할 수 있습니다.
생성자 오버로딩을 활용하면 다양한 방식으로 객체를 초기화할 수 있습니다.

class Person {
    String name;
    int age;

    // 기본 생성자
    Person() {
        this.name = "Unknown";
        this.age = 0;
    }

    // 매개변수가 있는 생성자
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
  • 같은 클래스에서 매개변수에 따라 생성자를 여러 개 만들 수 있습니다.
  • 기본 생성자와 매개변수 생성자를 함께 제공하면 유연한 객체 초기화가 가능합니다.

4. this() 키워드를 활용한 생성자 호출

같은 클래스 내의 다른 생성자를 호출할 때 this()를 사용할 수 있습니다. 코드 중복을 줄이고, 생성자 간 연결이 가능해집니다.

class Person {
    String name;
    int age;

    // 기본 생성자
    Person() {
        this("Unknown", 0);  // 다른 생성자 호출
    }

    // 매개변수 있는 생성자
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
  • this()를 사용하면, 생성자 내부에서 다른 생성자를 호출할 수 있어 코드 중복을 줄일 수 있습니다.

5. super()를 활용한 부모 생성자 호출

부모 클래스의 생성자를 호출하여 부모 필드를 초기화하는 역할을 합니다. 자식 객체가 생성될 때, 부모 필드도 함께 초기화됩니다.

class Parent {
    String name;

    Parent(String name) {
        this.name = name;
    }
}

class Child extends Parent {
    int age;

    Child(String name, int age) {
        super(name);
        this.age = age;
    }
}
  • 부모 객체가 물리적으로 존재하지 않아도, 부모 필드는 자식 객체 내부에서 초기화됩니다.
  • 자식 객체 내부에 부모 필드가 포함되므로, 부모 객체가 별도로 생성될 필요가 없습니다.

6. 상속 관계에서 부모 생성자가 자동 호출되는 이유

자바에서 상속 관계가 형성되면, 자식 클래스의 생성자는 부모 클래스의 생성자를 자동으로 호출합니다. 이는 부모의 필드와 메서드가 자식 객체 내부에서 올바르게 초기화되도록 보장하기 위한 것입니다.

자식 객체를 생성하기 위해서는 부모 객체의 부분이 먼저 존재해야 하므로, 부모 생성자가 먼저 실행됩니다.
따라서, 생성자의 첫 줄에는 항상 super();(부모 클래스의 기본 생성자 호출)가 자동으로 추가됩니다.
만약 부모 생성자가 오버로딩된 경우에는, 자식 클래스에서 명시적으로 super(매개변수);를 호출해야 합니다.

(1) 예제: 부모 생성자가 자동 호출되는 경우

class Parent {
    Parent() {  // 기본 생성자
        System.out.println("부모 클래스 생성자 호출!");
    }
}

class Child extends Parent {
    Child() {  // 자식 생성자
        System.out.println("자식 클래스 생성자 호출!");
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
    }
}

출력

부모 클래스 생성자 호출!
자식 클래스 생성자 호출!
  • Child() 생성자가 호출되면, 첫 줄에 자동으로 super();가 추가되어 부모 생성자가 먼저 실행됩니다.
  • 부모 클래스의 생성자가 실행된 후, 자식 클래스의 생성자가 실행됩니다.
  • 부모 필드가 자식 객체 내부에서 초기화되므로, 부모 객체가 따로 생성될 필요는 없습니다.

(2) 예제: 부모 생성자가 오버로딩된 경우 (super(매개변수); 명시)

class Parent {
    Parent(String msg) {  // 매개변수 있는 생성자만 존재
        System.out.println("부모 생성자: " + msg);
    }
}

class Child extends Parent {
    Child() {
        super("Hello from Child");  // 부모 생성자 명시적 호출
        System.out.println("자식 클래스 생성자 호출!");
    }
}
  • 부모 클래스에 기본 생성자가 없고 오버로딩된 생성자만 있을 경우, super(매개변수);를 반드시 명시해야 합니다.
  • 그렇지 않으면 컴파일 오류가 발생합니다.

7. 정리

  • 생성자는 객체를 초기화하는 역할이며, 객체를 생성하는 것이 아닙니다.
  • 객체 생성은 new 키워드에 의해 이루어지며, 생성자는 필드를 초기화합니다.
  • 생성자 오버로딩을 통해 다양한 방식으로 객체를 초기화할 수 있습니다.
  • this()를 사용하면 생성자 간 호출이 가능하여 코드 중복을 줄일 수 있습니다.
  • super()를 사용하면 부모 생성자를 호출하여 부모 필드를 초기화할 수 있습니다.
  • 클래스에 생성자가 없으면 기본 생성자가 자동으로 추가됩니다.
  • 객체가 생성될 때마다 생성자가 실행되며, 단 한 번만 호출됩니다.
  • 상속 관계에서는 부모 생성자가 자동으로 호출되며, 부모 생성자가 오버로딩된 경우에는 super(매개변수);를 명시해야 합니다.
profile
donggyun_ee

0개의 댓글