생성자

KKH_94·2023년 6월 8일
0

JAVA

목록 보기
18/36

자바에서 생성자(constructor)는 클래스의 인스턴스를 초기화하는 특별한 메서드입니다.

객체를 생성할 때 호출되며, 주로 객체의 멤버 변수를 초기화하고 객체의 초기 상태를 설정하는 데 사용됩니다.

생성자는 클래스 이름과 동일한 이름을 가지고 있으며, 반환 값이 없고 실제로 반환 타입을 선언하지 않습니다.

다음은 생성자의 특징과 사용 방법에 대한 상세한 설명입니다:

  1. 생성자의 특징

    • 생성자는 클래스의 인스턴스를 초기화하는 데 사용됩니다.
    • 생성자는 객체를 생성할 때 자동으로 호출됩니다.
    • 생성자는 클래스 이름과 동일한 이름을 가지고 있습니다.
    • 생성자는 반환 값이 없고, 반환 타입을 선언하지 않습니다.
    • 클래스에 생성자를 명시적으로 선언하지 않으면 컴파일러가 기본 생성자를 자동으로 생성합니다.
  2. 생성자의 사용 방법

    • 생성자는 new 키워드와 함께 사용하여 객체를 생성할 때 호출됩니다.
    • 생성자를 호출할 때는 클래스 이름 다음에 괄호를 사용합니다.
    • 생성자를 오버로딩(여러 개의 생성자를 선언)하여 다양한 초기화 방법을 제공할 수 있습니다.

다음은 생성자를 사용한 샘플 코드입니다:

public class Person {
    private String name;
    private int age;
    
    // 매개변수가 없는 디폴트 생성자
    public Person() {
        name = "Unknown";
        age = 0;
    }
    
    // 이름과 나이를 받는 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Getter 및 Setter 메서드 생략
    
    public static void main(String[] args) {
        // 기본 생성자를 사용하여 객체 생성
        Person person1 = new Person();
        System.out.println(person1.getName());  // "Unknown"
        System.out.println(person1.getAge());   // 0
        
        // 매개변수를 받는 생성자를 사용하여 객체 생성
        Person person2 = new Person("Alice", 25);
        System.out.println(person2.getName());  // "Alice"
        System.out.println(person2.getAge());   // 25
    }
}

위의 예제에서는 Person 클래스가 있고, 기본 생성자와 매개변수를 받는 생성자를 정의하였습니다. 디폴트 생성자는 name과 age를 초기화하고, 매개변수를 받는 생성자는 전달된 값을 사용하여 초기화합니다.

main 메서드에서는 두 가지 방식으로 객체를 생성하여 결과를 출력합니다.

class Child extends Parent {
    private int childData;

    public Child(int parentData, int childData) {
        super(parentData); // 부모 클래스의 생성자 호출
        this.childData = childData;
        System.out.println("Child constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child(10, 20);
    }
}

위 코드에서 Child 클래스는 Parent 클래스를 상속하고 있습니다.

Child 클래스의 생성자에서 super(parentData)를 호출하여 Parent 클래스의 생성자를 호출하고 있습니다. 이렇게 하면 Parent 클래스의 생성자가 먼저 실행되고, 그 후에 Child 클래스의 생성자가 실행됩니다.

이렇게 생성자를 사용하면 객체를 생성할 때 초기화 로직을 구현할 수 있고, 코드의 가독성과 유지 보수성을 향상시킬 수 있습니다.

  • 클래스를 정의할 때 생성자를 명시적으로 정의하지 않으면, 컴파일러는 디폴트 생성자를 자동으로 생성합니다. 디폴트 생성자는 매개변수 없이 객체를 초기화하는 역할을 합니다.

디폴트 생성자는 클래스의 멤버 변수들을 기본값으로 초기화합니다. 예를 들어, 정수형 변수는 0으로, 실수형 변수는 0.0으로, 참조형 변수는 null로 초기화됩니다. 또한, 클래스에 상속이 있는 경우에는 부모 클래스의 디폴트 생성자도 호출됩니다.

하지만 클래스에서 생성자를 하나 이상 명시적으로 정의한 경우에는 컴파일러는 디폴트 생성자를 자동으로 생성하지 않습니다. 이 경우 객체를 생성할 때는 명시적으로 정의된 생성자 중 하나를 호출해야 합니다.

아래는 생성자를 정의하지 않은 클래스의 예시입니다:

public class MyClass {
    private int myNumber;
    private String myString;
    
    // 생성자를 정의하지 않음
    
    // getter 및 setter 메서드 생략
    
    // 클래스의 다른 메서드들 생략
}

위의 예시에서 MyClass 클래스에는 생성자가 명시적으로 정의되지 않았습니다. 따라서 컴파일러는 디폴트 생성자를 자동으로 생성합니다. 이 디폴트 생성자는 매개변수 없이 객체를 초기화하며, myNumber 변수를 0으로, myString 변수를 null로 초기화합니다.

생성자를 명시적으로 정의하지 않고 디폴트 생성자를 사용하는 경우는 객체를 기본적으로 초기화하고자 할 때 유용합니다. 하지만 매개변수가 있는 생성자를 명시적으로 정의하는 것이 더 좋은 코드 설계를 할 수 있습니다.

생성자 빌드 패턴(Constructor Builder Pattern)

생성자 빌드 패턴(Constructor Builder Pattern)은 복잡한 객체 생성을 위해 사용되는 디자인 패턴입니다.

이 패턴은 많은 매개변수를 갖는 생성자를 간결하고 가독성이 높은 방식으로 구현할 수 있도록 도와줍니다.

아래는 생성자 빌드 패턴을 사용한 자바 코드 예시입니다.

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private String address;
    private String phoneNumber;

    private Person(Builder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.address = builder.address;
        this.phoneNumber = builder.phoneNumber;
    }

    // Getter methods...

    public static class Builder {
        private String firstName;
        private String lastName;
        private int age;
        private String address;
        private String phoneNumber;

        public Builder() {
        }

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setAddress(String address) {
            this.address = address;
            return this;
        }

        public Builder setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}

위의 코드에서 Person 클래스는 Builder 클래스와 함께 사용됩니다. Builder 클래스는 Person 객체를 구성하기 위한 매개변수를 설정하고, build() 메서드를 통해 실제 Person 객체를 생성합니다.

사용 예시는 다음과 같습니다:

Person person = new Person.Builder()
        .setFirstName("John")
        .setLastName("Doe")
        .setAge(30)
        .setAddress("123 Main St")
        .setPhoneNumber("555-1234")
        .build();

위 코드에서 Builder 객체를 생성한 후, setXxx() 메서드를 사용하여 필요한 매개변수를 설정합니다. 마지막에 build() 메서드를 호출하여 최종적으로 Person 객체를 생성합니다. 이렇게 하면 많은 매개변수를 가진 생성자를 호출하는 것보다 가독성이 높아지고, 객체 생성 시에 원하는 매개변수를 선택적으로 지정할 수 있습니다.

생성자 빌드 패턴은 불변성(Immutability)과 함께 사용될 때 특히 유용합니다. Person 클래스의 필드가 final로 선언되고, Builder 클래스에서 설정한 매개변수를 통해 객체를 생성하면, 생성된 객체는 변경할 수 없는 불변 객체가 됩니다.

자바에서는 명시적인 소멸자(Destructor)를 정의할 필요가 없습니다.


소멸자는 객체가 메모리에서 해제되기 전에 호출되는 메서드로, 주로 리소스의 정리나 정리 작업이 필요한 경우에 사용됩니다. C++과 같은 몇 가지 다른 언어에서는 객체가 소멸될 때 자동으로 호출되는 디스트럭터를 정의할 수 있습니다.

그러나 자바에서는 명시적인 디스트럭터 개념이 없으며, 메모리 관리는 가비지 컬렉터(Garbage Collector)가 처리합니다.

자바의 가비지 컬렉터는 동적으로 할당된 객체들을 추적하고, 더 이상 사용되지 않는 객체들을 자동으로 메모리에서 해제합니다. 객체가 더 이상 참조되지 않는 경우, 가비지 컬렉터는 해당 객체를 수거하여 메모리를 회수합니다. 이 과정에서 가비지 컬렉터는 더 이상 사용되지 않는 객체의 자원을 자동으로 정리합니다.

따라서 자바에서는 디스트럭터를 명시적으로 정의할 필요가 없으며, 가비지 컬렉터에 의해 메모리 관리와 자원 정리가 처리됩니다. 개발자는 주로 필요한 경우에는 명시적으로 리소스 해제를 수행하는 메서드를 정의하고, 객체의 사용이 끝난 후 해당 메서드를 호출하여 필요한 정리 작업을 수행하는 것이 좋습니다. 이렇게 하면 메모리 누수와 같은 문제를 방지할 수 있습니다.

profile
_serendipity

0개의 댓글