다음은 여러 종류의 생성자가 존재하는 클래스다.
public class ConstructorChaining {
public int val1;
public int val2;
public int val3;
public ConstructorChaining(int pVal1) {
this.val1 = pVal1;
}
public ConstructorChaining(int pVal1, int pVal2) {
this.val1 = pVal1;
this.val2 = pVal2;
}
public ConstructorChaining(int pVal1, int pVal2, int pVal3) {
this.val1 = pVal1;
this.val2 = pVal2;
this.val3 = pVal3;
}
}
위와 같이 짜게 되면 val1에 pVal1을 대입하는 코드가 두 번째, 세 번째 생성자에도 들어가면서 반복이 생기게 된다.
이러한 코드의 반복이 생기게 되면 유지보수를 하는데 있어 어려움이 생기게 된다.
예를 들어, 해당 클래스에서 val1 속성을 아예 없애버리고자 한다면?
위의 코드에서 val1에 값을 대입하는 라인을 일일히 찾아서 제거해야 한다.
이 반복은 Constructor Chaining을 통해 제거할 수 있다.
Constructor Chaining이란 한 생성자에서 동일 클래스에 있는 다른 생성자 코드를 호출하는 것이다.
즉 위의 예시에서는 두 번째 생성자에서 첫 번째 생성자를 호출하면 된다.
호출하는 방법은 다음과 같이 this를 사용하면 된다.
public class ConstructorChaining {
public int val1;
public int val2;
public int val3;
public ConstructorChaining(int pVal1) {
this.val1 = pVal1;
}
public ConstructorChaining(int pVal1, int pVal2) {
this(pVal1); // ConstructorChaining(pVal1)과 같은 기능을 합니다
this.val2 = pVal2;
}
public ConstructorChaining(int pVal1, int pVal2, int pVal3) {
this(pVal1, pVal2); // ConstructorChaining(pVal1, pVal2)과 같은 기능을 합니다
this.val3 = pVal3;
}
}
위와 같이 작성하면 코드의 반복을 없앨 수 있다.
인스턴스를 생성 시 무조건 실행됐으면 하는 코드가 있을 수 있다.
public class InitializationBlock {
int val1;
char val2;
int[] values;
// 1번 생성자 메서드
public InitializationBlock() {
int[] values = new int[10];
for(int i = 0; i < values.length; i++) {
values[i] = 1;
}
}
// 2번 생성자 메서드
public InitializationBlock(int pVal1) {
this(); // 코드 반복
this.val1 = pVal1;
}
// 3번 생성자 메서드
public InitializationBlock(char pVal2) {
this(); // 코드 반복
this.val2 = pVal2;
}
}
모든 생성자는 1번 생성자(인자값이 없는 생성자) 안의 코드를 실행해야 한다고 가정하자.
2, 3번 생성자는 모두 1번 생성자를 호출하게 되면서 코드의 반복(this())이 생기게 된다.
어차피 모든 생성자가 1번 생성자를 호출해야 한다면,
다음과 같이 Initialization Block을 사용하여 인스턴스가 생성될 때 무조건 실행되게 만들 수 있다.
public class InitializationBlock {
int val1;
char val2;
int[] values;
// Initialization Block
{
int[] values = new int[10];
for (int i = 0; i < values.length; i++) {
values[i] = 1;
}
}
// 1번 생성자
public InitializationBlock() {
// 기존에 있던 반복문을 Initialication Block란에 이동시킴
}
// 2번 생성자
public InitializationBlock(int pVal1) {
// 1번 생성자를 더이상 호출할 필요 없음
this.val1 = pVal1;
}
// 3번 생성자
public InitializationBlock(char pVal2) {
// 1번 생성자를 더이상 호출할 필요 없음
this.val2 = pVal2;
}
}
위와 같이 생성자 바깥 중괄호 블록 안에 무조건 실행됐으면 하는 코드를 적으면,
1, 2, 3번 생성자가 호출됐을 때 Initialization Block 안의 코드가 실행된 후 본 코드가 실행된다.
이렇게 하면 매 생성자마다 1번 생성자를 호출할 필요가 없어지게 된다.
'JAVA' 카테고리의 다른 글
제네릭 인터페이스 예시 (0) | 2020.01.06 |
---|---|
Enumeration Type에 대하여 (0) | 2020.01.05 |
포장 클래스와 등호(==) (0) | 2020.01.04 |
추상 클래스 예제 - 운전면허 (0) | 2020.01.03 |
클래스 상속의 함정 (0) | 2020.01.02 |