생성자
생성자는 인스턴스가 생성될 때 호출되는 ‘인스턴스 초기화 메서드’이다. 따라서 인스턴스 변수의 초기화 작업에 주로 사용되며, 인스턴스 생성 시에 실행되어야 하는 작업을 위해서도 사용된다.
생성자의 조건
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생성자는 리턴 값이 없다.
클래스이름(타입 변수명, 타입 변수명, ...) {
// 인스턴스 생성 시 수행될 코드,
// 주로 인스턴스 변수의 초기화 코드를 적는다.
}
class Point{
Point() { // 매개변수가 없는 생성자.
...
}
Point(int x, int y) { // 매개 변수가 있는 생성자
...
}
...
}
연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다.
기본 생성자(Default Constructor)
모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 한다.
컴파일할 때, 소스파일(*. java)의 클래스에 생성자가 하나도 정의되지 않은 경우 컴파일러는 자동적으로 아래와 같은 내용의 기본 생성자를 추가하여 컴파일한다.
클래스이름(){} // 기본 생성자
Point(){} // Point클래스의 기본 생성자
인스턴스 초기화 작업이 요구되지 않는다면 생성자를 정의하지 않고 컴파일러가 제공하는 기본 생성자를 사용하는 것도 좋다.
class Data_1 {
int value;
}
class Data_2 {
int value;
Data_2(int x) { // 매개변수가 있는 생성자.
value = x;
}
}
class Ex6_11 {
public static void main(String[] args) {
Data_1 d1 = new Data_1();
Data_2 d2 = new Data_2(); // compile error발생
}
}
Data_1에는 정의되어 있는 생성자가 하나도 없으므로 컴파일러가 기본 생성자를 추가해주었지만, Data_2에는 이미 생성자 Data_2(int x)가 정의되어 있으므로 기본 생성자가 추가되지 않았기 때문에 오류가 발생한다.
컴파일러가 자동적으로 기본 생성자를 추가해주는 경우는 ‘클래스 내에 생성자가 하나도 없을 때’뿐이라는 것을 명심해야 한다.
매개변수가 있는 생성자
생성자도 메서드처럼 매개변수를 선언하여 호출 시 값을 넘겨받아서 인스턴스의 초기화 작업에 사용할 수 있다.
class Car {
String color; // 색상
String gearType; // 변속기 종류 - auto(자동), manual(수동)
int door; // 문의 개수
Car() {} // 기본생성자
Car(String c, String g, int d) { // 생성자
color = c;
gearType = g;
door = d;
}
}
매개변수가 있는 생성자 Car(String color, String gearType, int door)를 사용한다면 인스턴스를 생성하는 동시에 원하는 값으로 초기화를 할 수 있게 된다.
this()
같은 클래스의 멤버들 간에 서로 호출할 수 있는 것처럼 두 가지 조건을 만족시킨다면 생성자간에도 서로 호출이 가능하다.
- 생성자의 이름으로 클래스 이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
Car(String color) {
door = 5; // 첫 번째 줄
Car(color, "auto", 4); // 에러1. 생성자의 두번째 줄에서 다른 생성자 호출
} // 에러2. this(color, "auto", 4);로 해야함
에러 발생 이유
- 생성자 내에서 다른 생성자를 호출할 때는 클래스 이름 'Car'대신 'this'를 사용해야 함.
- 생성자 호출은 첫 번째 줄에서 호출해야 함.
생성자에서 다른 생성자를 첫 줄에서만 호출이 가능하도록 한 이유는 생성자 내에서 초기화 작업 도중에 다른 생성자를 호출하게 되면, 호출된 다른 생성자 내에서도 멤버 변수들의 값을 초기화를 할 것이므로 다른 생성자를 호출하기 이전의 초기화 작업이 무의미해질 수 있기 때문이다.
class Car2 {
String color; // 색상
String gearType; // 변속기 종류 - auto(자동), manual(수동)
int door; // 문의 개수
Car2() {
this("white", "auto", 4);
}
Car2(String color) {
this(color, "auto", 4);
}
Car2(String color, String gearType, int door) {
this.color = color;
this.gearType = gearType;
this.door = door;
}
}
생성자 Car2()에서 또 다른 생성자 Car2(String color, String gearType, int door)를 호출하였다. 이처럼 생성자 간의 호출에는 생성자의 이름 대신 this를 사용해야만 하므로 ‘Car2’ 대신 ‘this’를 사용했다
this
‘this’는 참조 변수로 인스턴스 자신을 가리킨다. 참조 변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼, ‘this’로 인스턴스 변수에 접근할 수 있는 것이다.
this 인스턴스 자신을 가리키는 참조 변수, 인스턴스의 주소가 저장되어 있다. 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
this(), this(매개변수) 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
변수의 초기화
변수를 선언하고 처음으로 값을 저장하는 것을 ‘변수의 초기화’라고 한다.
멤버 변수는 초기화를 하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화가 이루어지므로 초기화하지 않고 사용해도 되지만, 지역변수는 사용하기 전에 반드시 초기화해야 한다.
class InitTest{
int x; // 인스턴스 변수
int y = x; // 인스턴스 변수
void method1() {
int i; // 지역 변수
int j = i; // 에러. 지역변수를 초기화하지 않고 사용
}
}
인스턴스 변수 x는 초기화를 해주지 않아도 자동적으로 int형의 기본값인 0으로 초기화되므로, ‘int y = x;’와 같이 할 수 있다. x의 값이 0이므로 y 역시 0이 저장된다.
하지만, method1()의 지역변수 i는 자동적으로 초기화되지 않으므로, 초기화되지 않은 상태에서 변수 j를 초기화하는 데 사용될 수 없다. 컴파일하면, 에러가 발생한다.
멤버 변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택이지만, 지역변수의 초기화는 필수이다.
멤버 변수의 초기화
- 클래스 변수(cv) 초기화 → 인스턴스 변수(iv) 초기화
- 자동 초기화 → 명시적 초기화(간단) → 초기화 블록, 생성자(복잡)
명시적 초기화
변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다.
class Car{
int door = 4; // 기본형(primitive type) 변수의 초기화
Engine e = new Engine(); // 참조형(reference type) 변수의 초기화
//...
}
보다 복잡한 초기화 작업이 필요할 때는 ‘초기화 블록(initialization block)’ 또는 생성자를 사용해야 한다.
초기화 블럭
초기화 블록에는 ‘클래스 초기화 블럭’과 ‘인스턴스 초기화 블럭’ 두 가지 종류가 있다.
클래스 초기화 블럭 : 클래스 변수의 복잡한 초기화에 사용된다.
인스턴스 초기화 블럭 : 인스턴스 변수의 복잡한 초기화에 사용된다.
초기화 블록을 작성하려면, 인스턴스 초기화 블럭은 단순히 클래스 내에 블럭{}만들고 그 안에 코드를 작성하기만 하면 된다. 그리고 클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 단순히 static을 덧붙이기만 하면 된다.
'Server > 자바의정석' 카테고리의 다른 글
[Java 입문] Super (0) | 2022.09.28 |
---|---|
[Java 입문] 상속 (0) | 2022.09.27 |
[Java 입문] Static 메서드와 인스턴스 메서드 (0) | 2022.09.27 |
[Java 입문] 매개변수 (0) | 2022.09.27 |
[Java 입문] 메서드 (0) | 2022.09.27 |