JAVA

생성자

고민말고생각하는사람 2024. 1. 15. 00:00

생성자란?

객체를 초기화하기 위해 사용하는 특별 메서드이다.

객체가 생성될 때 자동으로 호출되며, 주로 멤버 변수 초기에 사용된다.

 

객체를 생성하는 시점에 어떤 작업을 하고 싶다면 생성자(Constructor)를 이용한다.

 

짧은 설명만으론 모르겠다. 예시를 들어보자.

public class Food {
	 String name;
     String description;
     int price;
}

위와 같이 Food class 가 있다. 초기화 해서 사용 해보자.

public class FoodMain{
	public static void main(String[] args){
    	Food food1 = new Food();
        food1.name = "정어리 대가리 파이";
        food1.description = "영국의 전통 음식";
        food1.price = 4444;
        
        Food food2 = new Food();
        food2.name = "강낭콩 절임을 얹은 식빵";
        food2.description = "혓바닥이 비명을 지르는 맛을 낸다";
        food2.price = 4444444;
    }
}

 

기초부터 차근차근 올라오고 있다면 아래와 같은 순서로 작성했을 것이다.

 

1단계. 인스턴스를 생성한다.

2단계. 인스턴스의 멤버변수에 접근해 값을 넣는다.

 

인스턴스를 제대로 쓰기 위해선 클래스에 선언했던 멤버 변수를 모두 초기화 해주어야 한다.

만약 초기화를 중간 중각 빼먹는 다면 어떻게 될까?

위의 코드는 '음식'이 테마이니 메뉴판으로 예시를 들어 보자.

품명 설명 가격
정어리 대가리 파이 영국의 전통 음식. 정어리의 눈알이.. 0
null 혓바닥이 비명을 지를 것 같다. 4444444

실수로 Food의 멤버변수의 초기화를 빼먹으면 위와 같은 모양이 될 것이다.

계산 시 음식을 무료로 제공해야 하고,

헛바닥이 비명을 지르는 음식은 NullPointerException을 터뜨릴 게 분명하다.

 

이런 사고를 미연에 방지하기 위해

1단계, 2단계를 하나로 합친다.

=> 인스턴스를 생성하면서 멤버변수를 초기화 한다.

이렇게 하면 위와 같이 구멍 뚫린 메뉴판이 만들어 질 일이 없을 것이다.

 

사고를 방지하는 방법은 알았다. 그럼 이 동작을 어디서 수행하면 좋을까?

1. Food 가 외부에서 값을 받아 알아서 처리하게 한다.

2. Food 를 사용하는 곳에서 Food 를 초기화 한다.

 

객체지향적인 프로그래밍을 위해선, 연관이 있는 속성, 행동을 하나로 응집 시켜야 옳다.

파악하기 쉽고, 읽기 쉽고, 이해하기도 쉬워지기 때문이다.

따라서, Food의 초기화는 Food가 하는 것이 옳겠다.

public class Food {
	 String name;
     String description;
     int price;
     
     Food(String name, String description, int price){
     	this.name = name;
        this.description = description;
        this.price = price;
     }
}

Food 가 스스로에 대한 초기화를 진행할 수 있도록 생성자를 작성 했다.

public class FoodMain{
	public static void main(String[] args){
    	Food food1 = new Food("정어리 대가리 파이", "영국의 전통 음식", 4444);  
      	Food food2 = new Food("강낭콩 절임을 얹은 식빵", "혓바닥이 비명을 지르는 맛을 낸다", 444444);
//    	Food food3 = new Food();	// 컴파일 에러
    }
}

코드가 좀 더 짧아지고 견고해졌다.

인스턴스를 생성할 때, 정의한 생성자대로 인자를 넘겨주지 않으면, 컴파일 에러가 발생하게 된다.

따라서, 멤버변수 초기화 누락에 따른 사이드 이펙트는 더 이상 발생하지 않게 됐다.

 

생성자 규칙

이러한 생성자는 몇 가지 규칙이 있다. 규칙은 아래와 같다.

1. 생성자의 이름은 클래스의 이름과 같아야 함. => 클래스명의 암묵적 룰 '첫 글자는 대문자' 따라서 - (후략) 

2. 생성자는 반환타입이 없고, void도 사용하지 않음. 비워둬야 한다. => 특별 메서드임.

3. 생성자는 클래스 내부에 정의되며, 메서드와 동일한 위치에 작성됨.

4. 객체를 생성하기 위해 new 키워드와 함께 호출됨. ex ) Food food = new food();

5. 생성자는 오버로딩이 가능함. (매개변수가 다른 생성자 여러 개 정의 가능)

6. 상속이 안 됨.

7. 명시적으로 선언하지 않는 경우, 컴파일러에 의해 '기본 생성자'가 제공됨. Food class 에  Food() 를 정의하지 않았는데 사용 가능한 것은 이 때문임. => 반대로, 명시적으로 선언된 생성자가 있다면, 기본 생성자는 자동으로 생성되지 않음.