다트 언어에서는 클래스의 생성자를 다양하게 이용할 수 있는데 명명된 생성자는 가장 중요하고 가장 자주 사용합니다. 명명된 생성자는 이름이 있는 생성자라는 의미로, 한 클래스에 이름이 다른 생성자를 여러 개 선언하는 기법입니다. 다른 프로그래밍 언어에서도 생성자를 여러 개 선언할 수 있는 오버로딩 기능을 제공하지만, 똑같은 이름으로 매개변수나 변환 타입만 다르게 선언해야 하므로 다트와는 차이가 있습니다.
예를 들어 다음 코드는 자바 언어로 생성자 오버로딩을 구현한 예입니다. 하지만 다트에서는 이러한 오버로딩을 지원하지 않습니다. 대신 다른 기법으로 생성자를 여러 개 선언할 수 있습니다.
// 자바로 작성한 생성자 오버로딩
public class MyClass {
MyClass() {}
MyClass(int data1) {}
MyClass(int data1, int data2) {}
}
명명된 생성자는 한 클래스에 이름을 다르게 해서 여러 생성자를 정의하는 기법입니다. 즉, 다트에서는 클래스와 같은 이름뿐만 아니라 다른 이름으로도 생성자를 만들 수 있습니다. 명명된 생성자는 클래스와 생성자 이름을 점(.)으로 연결해서 작성합니다.
한 클래스에 클래스와 같은 이름의 생성자는 하나만 정의할 수 있지만, 명명된 생성자는 클래스와 다른 이름으로 여러 개 정의할 수 있습니다.
// 명명된 생성자 선언
class MyClass {
MyClass() { }
MyClass.first() { }
MyClass.second() { }
}
이렇게 선언한 명명된 생성자로 객체를 만드는 코드는 오른쪽과 같습니다.
// 명명된 생성자로 객체 생성
var obj1 = MyClass();
var obj2 = MyClass.first();
var obj3 = MyClass.second();
다트에서 생성자 오버로딩 대신 명명된 생성자를 제공하는 이유는 무엇인가요?
오버로딩으로 선언한 생성자로 객체를 생성할 때는 매개변수 부분을 보고 어떤 생성자를 호출할지 결정합니다. 그런데 생성자에 이름을 부여하면 생성자를 구분하기가 더 쉬워집니다. 다트에서 생성자 오버로딩 대신 명명된 생성자를 제공하는 이유는 이처럼 각각의 생성자를 좀 더 명료하게 구분하려는 의도가 아닐까 싶습니다.
this()로 다른 생성자 호출하기
한 클래스에 생성자를 여러 개 선언하면 생성자에서 다른 생성자를 호출해야 할 수도 있습니다. 이렇게 하면 객체를 생성할 때 생성자가 중첩되어 호출됩니다.
예를 들어 아래처럼 기본 생성자 MyClass()와 명명된 생성자 MyClass.first()를 선언하고 MyClass.first()가 호출될때 MyClass()도 실행하고 싶습니다. 이때 this() 구문을 이용하면 되는데 this()는 생성자의 {} 안쪽 본문에 작성할 수 없습니다.
// this() 잘못된 호출 예
class MyClass {
MyClass(int data1, int data2) {
print('MyClass() call....');
}
MyClass.first(int arg) {
this(arg, 0); // 오류
}
}
다른 생성자를 호출하는 this()는 생성자의 콜론(:) 오른쪽 초기화 목록에 작성해야 합니다. 그런데 초기화 목록에 this() 호출문을 작성하면 생성자 본문을 작성할 수 없습니다. 따라서 다음처럼 본문 영역 나타내는 { }를 작성하는 것만으로 오류가 발생합니다.
// this() 잘못된 호출 예
class MyClass {
MyClass(int data1, int data2) {
print('MyClass() call...');
}
MyClass.first(int arg) : this(arg,0) { } // 오류
}
다음은 명명된 생성자가 호출될 때 this()로 기본 생성자를 호출하는 올바른 코드입니다.
// 기본 생성자 중첩 호출
class MyClass {
MyClass(int data1, int data2) {
print('MyClass() call....');
}
MyClass.first(int arg) : this(arg, 0); // 성공
}
this()를 이용할 때 또 하나 규칙은 this() 호출문 외에 다른 구문을 사용할 수 없습니다. 즉, 콜론 오른쪽에는 this()만 작성해야 합니다.
// this() 잘못된 호출 예
MyClass.first(int arg) : this(arg,0), this.data1=arg1; // 오류
또한 클래스에 작성된 명명된 생성자도 this()로 호출할 수 있습니다. this.first() 처럼 this 뒤에 생성자 이름을 붙여 주면 됩니다.
// 명명된 생성자 중첩 호출
class MyClass {
late int data1;
late int data2;
MyClass(this.data1, this.data2);
MyClass.first(int arg) : this(arg, 0); // 기본 생성자(MyClass) 호출
MyClass.second() : this.first(0); // 명명된 생성자(MyClass.first) 호출
}
'Flutter' 카테고리의 다른 글
상수 생성자 (0) | 2024.11.14 |
---|---|
팩토리 생성자 (0) | 2024.11.14 |
생성자와 멤버 초기화 (0) | 2024.11.13 |
클래스와 객체 (0) | 2024.11.13 |
실행 흐름 제어하기 (0) | 2024.11.13 |