생성자, 기본 생성자
생성자 (constructor)
- 인스턴스가 생성될 때마다 호출되는 '인스턴스 초기화 메서드'
- 인스턴스 생성시 수행할 작업(iv 초기화)에 사용
생성자는 인스턴스를 초기화해주는 메서드다. 인스턴스는 객체(iv묶음)이다.
즉, 생성자는 iv를 초기화 하는 메서드다.
iv초기화가 뭐냐면, 아래와 같이 진행한다.
참조변수 t를 선언하고 Time객체를 생선한다.
Time객체에는 멤버가 3개있다. hour, minute, second가 있고, 0으로 자동초기화 되어있다.
그리고 12시 34분 56초를 저장하려면, 내가 원하는 12시 34분 56초로 초기화를 해주어야 한다.
이런식으로 하는 것을 초기화라고 한다.
위의 과정을 보면,
1. 객체 생성
2. iv 초기화
이런과정을 거쳐야한다. 근데 조금 번거로운 것 같기도 하다.
위의 과정을 아래처럼 한줄로 할 수 있으면 훨씬 직관적이고 편리할 것이다.
이게 바로 생성자호출이다.
생성자'Time()'가 하는 일은, 인스턴스 초기화이다.
인스턴스를 만들고 해당 인스턴스에 원하는 값을 세팅하는 것이다.
일반적으로 생성자가 존재하는 목적이 객체 (iv)초기화지만, 메서드이기 때문에 다른 작업을 넣을 수도 있다. {}안에 작업할 문장을 넣으면 된다.
그리고, Time()같은 형태는 기본생성자지만, Time(12, 34, 56)처럼 그외의 생성자같은 경우에는 우리가 생성자를 추가해줘야 한다.
생성자 작성 규칙
- 이름이 클래스 이름과 같아야 한다.
- 리턴값이 없다. (void 안붙임)
- 모든 클래스는 반드시 1개이상의 생성자를 가져야 한다.
첫번째 규칙은, 생성자 이름이 클래스 이름과 같아야 한다.
밑의 Card클래스 예시를 보면, 클래스 이름과 생성자 이름이 동일한 것을 볼 수 있다.
해당 예시에서 생성자 이름이 같은게 2개 존재할 수 있는 이유는, 앞서 공부했던 "오버로딩"기능 때문에 가능하다.
자세히 보면, 매개변수가 다른 것을 알 수 있다.
생성자 작성의 또다른 규칙은, 리턴값이 없다.(void 안붙임)
초기화는 대입문이다. 대입문은 결괄르 반환할 것이 없다. 대입만 하면 된다. 그래서 리턴값이 없다.
원래 메서드에서는 리턴값이 없으면 'void'를 붙여야 한다.
그러나, 생성자인 경우에는 void를 붙이지 않는다.
생성자 작성의 세번째 규칙은 모든 클래스는 반드시 1개이상의 생성자를 가져야 한다.
Card객체 만들면, Card c = new Card(); 이렇게 작성하는데, Card()이 부분이 생성자 호출이다.
그런데, 앞서 말했듯, 생성자는 직접 생성해줘야 하는데, 우리는 생성자를 만들어 준 적이 없다.
만들어 준 적이 없는데 어떻게 호출했을까?
Card(); 이것은 기본 생성자이다. 이것은 생성자가 1개도 없는 경우에 컴파일러가 추가를 해주는 기본생성자이다.
그래서 원래는 만들어서 써야하는데, 만들지 않았음에도 사용할 수 있는 것이다.
기본 생성자
- 매개변수가 없는 생성자
- 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
생성자에 매개변수가 없는 것을 기본 생성자라고 한다. 우선은 하는일이 아무것도 없다.
기본생성자를 원래는 직접 작성해야 한다.
그러나, 클래스에 생성자가 1개도 없을 때에만, 컴파일러가 자동으로 추가해준다.
기본 생성자는, 다른생성자가 있어서 쓸모없는 것 같더라도, 꼭 넣어주어야 한다.
앞으로 생성자에 대해 더 공부하다보면 그 이유를 알게 될텐데,
기본 생성자는 컴파일러에 의존하지 말고 항상 만들어 주는 습관을 가지도록 노력하자.
예제를 보자.
여기보면, 클래스가 3개있다. Data1, Data2, 메인메서드 클래스가 있는데,
메인메서드를 보면, Data1의 객체를 생성한다. 이때는 문제가 없다. 그런데, Data2의 객체를 만들때는 copile errorr가 발생했다.
컴파일 에러 내용을 살펴보면,
canont resolve symbol이면 이름에 문제가 있는 것이다. Data_2라는 것을 못찾겠다라는 것이다.
그 이유는 Data_2의 클래스를 보면, 생성자가 1개 있다.
메인메서드에서 new Data_2();에서 Data_2();부분이 기본 생성자 호출이다.
근데, 이 기본생성자가 Data_2클래스안에 없어서 에러가 난 것이다.
에러가 나지 않게 하려면, Data_2클래스에 우리가 직접 기본생성자 Data2(){}를 추가 해줘야 한다.
어 그런데 Data_1클래스에는 생성자가 없는데 왜 메인메서드에서 객체를 생성하면 에러가 나지 않을까?
그 이유는, Data_1클래스는 생성자가 하나도 없기 때문이다.
- 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
이 규칙에 따라서 생성자가 하나도 없는 Data_1(); 는 에러가 발생하지 않고 컴파일러가 기본 생성자를 자동추가 해주지만,
Data_2는 매개변수가 있는 생성자가 존재했는데, 메인메서드에서 기본 생성자를 호출하니 에러가 발생한 것이다.
실제로 위의 코드에서
좌측 부분을 컴파일 하면, 코드가 우측처럼 바뀌어 실행된다.
원래는 우리가 추가해주어야 하는데, 자바에서 친절하게 자동으로 추가해준 것이다.
이러한 상황을 예방하기 위해
기본 생성자는 컴파일러에 의존하지 말고 항상 만들어 주는 습관을 가지도록 노력하자.
매개변수가 있는 생성자
이번에는 매개변수가 있는 생성자에 관한 내용이다.
대부분 매개변수가 있다. 그럴 경우,
생성자가 없는 경우에는,
이런식으로 객체를 생성한 후, 초기화를 해주어야 한다.
그런데, 위와 같은 생성자가 있는 경우에는,
Car c = new Car("White", "auto", 4);로 간단하게 초기화를 작성할 수 있다.
매개변수가 있는 생성자의 경우에는, 사실은 밖에서 초기화를 할 코드를 클래스 안으로 감춘 것 뿐이다.
그러나, 객체를 생성할 때는 코드가 간결해진다.
설계도를 만든 사람이 매개변수있는 생성자를 한번만 잘 작성해 놓으면, 사용하는 쪽에서는 편리하게 여러번 사용할 수 있다.
이런 생성자를 제공해야하는 이유, 그리고 생성자가 필요한 이유는 이렇게 코드가 클린해지기 때문이다.
여러줄 써야 할 것을, 생성자로 인해 간단히 쓸 수 있다. 그래서 생성자를 쓰는 것이다
생성자를 사용한 코드의 실행과정을 살펴보면,
1. 참조변수 생성
2. new연산자가 클래스를 보고 객체 생성
3. 생성자 호출되어 객체(iv) 초기화
4. 객체와 참조변수 연결 위한 대입연산으로 주소 저장 (new 연산자의 반환값은 객체주소임)
기본 생성자는 컴파일러에 의존하지 말고 항상 만들어 주는 습관을 가지도록 노력하자.
'JAVA' 카테고리의 다른 글
변수의 초기화, 멤버 변수의 초기화 (0) | 2022.03.29 |
---|---|
생성자 this(), 참조변수 this (0) | 2022.03.29 |
오버로딩 (1) | 2022.03.28 |
static메서드와 인스턴스 메서드 (0) | 2022.03.28 |
참조형 매개변수, 참조형 반환타입 (0) | 2022.03.27 |
댓글
이 글 공유하기
다른 글
-
변수의 초기화, 멤버 변수의 초기화
변수의 초기화, 멤버 변수의 초기화
2022.03.29 -
생성자 this(), 참조변수 this
생성자 this(), 참조변수 this
2022.03.29 -
오버로딩
오버로딩
2022.03.28 -
static메서드와 인스턴스 메서드
static메서드와 인스턴스 메서드
2022.03.28