7.3.1 생성자의 특성 7.3.2 기본 생성자의 자동 추가

jh·2022년 1월 30일
0

Do it! 자바 완전 정복

목록 보기
64/70

생성자 constructor는 객체를 생성하는 역할을 지닌 클래스의 내부 구성 요소다. 또한 객체 내에 포함되는 필드의 초기화 또한 주로 생성자 내에서 수행한다.

7.3.1 생성자의 특징
생성자를 작성할 때 꼭 지켜야 하는 문법적 규칙은 2가지다. 첫 번째는 반드시 클래스명과 동일한 이름으로 지어야 한다. 클래스명과 다르면 더 이상 생성자가 아니다. 두 번째는 메서드와 비슷한 구조를 지니고 있지만 리턴 타입이 없다. 여기서 헷갈리지 말아야 할 것이 '리턴 타입이 없다'와 '리턴하지 않는다(void)'는 전혀 다른 이야기라는 것이다. 생성자는 아예 리턴 타입 자체가 없다는 말이다. 이러한 2가지 특징을 반영한 생성자의 문법 구조는 다음과 같다.

🌾생성자의 문법 구조

클래스명(입력매개변수){
} // 클래스명 : 생성자명은 클래스명과 동일 // 입력매개변수는 생략 가능class A {
            A(){
                //...
            }
        }

7.3.2 기본 생성자의 자동 추가
이쯤에서 또 이상한 생각이 든다. 우리는 A a = new A()와 같이 생성자를 호출해 객체를 만들어 왔지만 지금까지 생성자를 만든 기억은 없다. 지금까지 생성자를 만들지 않아도 정상적으로 객체가 생성됐던 이유는 생성자를 포함하지 않는 클래스에게 컴파일러가 기본 생성자를 추가해 줬기 때문이다. 여기서 기본 생성자는 입력매개변수가 없는 생성자를 말한다.

그 이유는 무엇일까? 클래스와 객체를 각각 '붕어빵 기계'와 '붕어빵'이라고 했다. 그렇다면 생성자는 '붕어빵을 직는 기능'정도라고 생각할 수 있다. 그러면 생성자가 없는 클래스는 붕어빵을 찍을 수 없는 붕어빵 기계를 만든 셈이다. 즉 전혀 존재 이유가 없는 것이다.

생성자가 없는 클래스 = 붕어빵을 찍을 수 없는 붕어빵 기계
-> 존재 이유 없음
=> 모든 클래스는 생성자를 포함해야 함

그래서 컴파일러는 생성자가 없는 클래스를 만들면 적어도 1개의 생성자가 필요하므로 입력매개변수가 없는 기본 생성자를 추가해 주는 것이다.

🌾생성자를 포함시키지 않은 클래스

        class A{
            int m;
            void work(){...}
        }

🌾컴파일러로 기본 생성자가 자동으로 추가된 클래스

class A{
    int m;
    void work(){...}
    A(){                //컴파일러가 자동으로 기본 생성자 추가
        
    }
}

생성자가 호출되는 것만으로 객체가 내부적으로 생성된다. 생성자의 실행문 즉 생성자의 중괄호 안은 객체가 생성된 이후 할 일이 작성되는 부분이다. 일반적으로 여기에서 필드를 초기화한다. 따라서 컴파일러가 추가해주는 기본 생성자 안은 텅 비어있다.
다음 예제를 샐펴보자 A 클래스에 생성자가 있지만 기본 생성자는 아니다. 그렇다면 컴파일러는 클래스 A에 기본 생성자가 없으므로 기본 생성자를 추가해줄까? 전혀 아니다. 앞에서 말했듯이 객체를 찍어낼 수 없는 클래스는 존재 이유가 없으므로 기본 생성자를 추가해준 것이다. 클래스 A는 이미 있는 생성자를 사용해 객체를 생성할 수 있다. 그러므로 컴파일러가 기본 생성자를 추가해줄 이유가 전혀 없다.

🌾기본 생성자가 아닌 생성자를 포함하고 있는 클래스

class A{
    int m;
    void work(){...}
    A(int k){
        m = k;            // 생성자가 이미 있으므로 기본 생성자는 추가되지 않음.
    }
}

실습

class A{
    int m;
    void work(){
        System.out.println(m);
    }
/*    A(){
        
                    생성자를 포함하지 않으면 컴파일러가 기본 생성자를 자동으로 추가
    }*/
}

class B{
    int m;
    void work(){
        System.out.println(m);
    }
    B(){
              // 기본 생성자를 직접 정의
    }
}

class C {
    int m;
    void work() {
        System.out.println(m); // 생성자로 넘어온 값 
    }
    C(int a){ //입력매개변수를 포함하고 있는 생성자 정의
        m = a; //입력매개변수로 전다로딘 값으로 필드 초기화
    }
}

public class jh {
    public static void main(String[] args) {
        
        //클래스의 객체 생성
        A a = new A(); // 컴파일러가 자동으로 추가한 기본 생성자를 호출해 객체 생성
        B b = new B(); // 직접 정의한 기본 생성자를 호출해 객체 생성 
        //C c = new C(); // 기본 생성자 호출 불가능 
        C c = new C(3); // 직접 정의한 생성자를 호출해 객체 생성
        
        //메서드 호출
        a.work();
        b.work();
        c.work();
    }
}

결과

profile
코딩 공부 중...

0개의 댓글