class Point {
double? x; // 인스턴스 변수 x를 선언합니다. 초기값은 null입니다.
double? y; // 인스턴스 변수 y를 선언합니다. 초기값은 null입니다.
double z = 0; // 인스턴스 변수 z를 선언합니다. 초기값은 0입니다.
}
초기화하지 않은 인스턴스 변수는 null 값을 갖습니다. 모든 인스턴스 변수는 암시적으로 setter, getter 메서드가 생성됩니다. 초기화하지 않은 Non-final 인스턴스 변수와 late final 인스턴스 변수도 암시적으로 setter 메서드를 생성합니다.
선언된 위치에서 Non-late 인스턴스 변수를 초기화하면 인스턴스가 생성될 때 값이 설정되며, 이는 생성자와 초기화 목록이 실행되기 전에 이루어 집니다.
class Point {
double? x; // 인스턴스 변수 x를 선언합니다. 초기값은 null입니다.
double? y; // 인스턴스 변수 y를 선언합니다. 초기값은 null입니다.
}
void main() {
var point = Point();
point.x = 4; // x에 대해 setter 메서드를 사용합니다.
assert(point.x == 4); // x에 대해 getter 메서드를 사용합니다.
assert(point.y == null); // 기본값은 null입니다.
}
인스턴스 변수는 final로 설정할 수 잇으며, 이 경우 딱 한번만 초기화할 수 있습니다. final 및 non-late 인스턴스 변수는 아래의 방법으로 초기화 할 수 있습니다.
변수 선언 시점에 초기화
생성자 매개변수를 사용해 초기화
생성자의 초기화 목록(Initializer list)을 사용해 초기화
class ProfileMark {
final String name;
final DateTime start = DateTime.now(); // 선언 시 초기화합니다.
ProfileMark(this.name); // 생성자 매개변수를 사용해 초기화합니다.
ProfileMark.unnamed() : name = ''; // 생성자 초기화 목록을 사용해 초기화합니다.
}
만약 생성자 바디에서 final로 선언된 인스턴스 변수에 값을 할당해야하는 경우 다음 중 하나의 방법을 사용하세요.
late final을 사용
팩토리 생성자(Factory constructor)를 사용
아래 코드는 설정된 x, y 각 좌표 크기보다 2배 큰 크기로 좌표를 설정하여 점 인스턴스를 생성합니다. 클래스 바디에서 x, y 값이 2를 곱하는데 x, y는 final로 선언 되었기 때문에 setter가 존재하지 않고 컴파일 에러가 발생합니다.
class DoublingPoint {
final int x;
final int y;
DoublingPoint(int x, int y) {
// Error: The setter 'x' isn't defined for the class 'DoublingPoint'.
this.x = x * 2;
// Error: The setter 'y' isn't defined for the class 'DoublingPoint'.
this.y = y * 2;
}
}
void main() {
final dp = DoublingPoint(1, 1);
print("${dp.x}, ${dp.y}");
}
late 키워드를 final 키워드 앞에 추가하면 setter가 생성되어 클래스 바디에서 final 인스턴스 변수를 초기화하는게 가능합니다. late final 인스턴스 변수는 단 한번만 초기화가 가능하기 때문에 초기화 후 추가로 값을 변경하려고 시도하면 런타임 에러를 일으킵니다.
class DoublingPoint {
// late final 필드는 setter를 생성합니다.
late final int x;
late final int y;
DoublingPoint(int x, int y) {
this.x = x * 2;
this.y = y * 2;
// Uncaught Error: LateInitializationError: Field 'x' has already been initialized.
// this.x = x * 3;
}
}
void main() {
final dp = DoublingPoint(1, 1);
print("${dp.x}, ${dp.y}");
}
late final로 선언하면 암시적으로 setter가 생성되므로 반드시 원하는 시점에 초기화하는 것을 잊지 말아야 합니다. 초기화 코드가 누락될 경우 해당 인스턴스를 사용하는 쪽에서 객체에 대해 의도치 않은 변경을 가할 수 있어 주의가 필요합니다.
생성자 바디에서 final 인스턴스 변수를 초기화하는 다른 방법은 팩터리 생성자를 사용하는 방법입니다.
class Point {
final int x;
final int y;
// Point 클래스 내부에서만 접근 가능한 비공개 생성자 _internal을 정의합니다.
Point._internal(this.x, this.y);
// 팩터리 생성자에서 2를 곱한 값을 _internal에 전달하여 변수를 초기화합니다.
factory Point.doubling(int x, int y) {
return Point._internal(x * 2, y * 2);
}
}
void main() {
final dp = Point.doubling(1, 1);
print("${dp.x}, ${dp.y}");
}