Dart에서는 getter와 setter를 사용하여 객체의 속성에 대한 접근과 수정을 제어할 수 있습니다. getter와 setter는 메서드처럼 작동하지만, 속성처럼 접근할 수 있습니다.
Getter는 객체의 속성값을 가져오는 메서드입니다. Dart에서는 get
키워드를 사용하여 getter를 정의할 수 있습니다. getter에는 매개변수를 위한 괄호를 사용하지 않는다.
class Circle {
double radius;
Circle(this.radius);
// pi 값을 곱해서 원의 둘레를 계산하는 getter
double get circumference => 2 * 3.141592653589793 * radius;
// pi 값을 곱해서 원의 넓이를 계산하는 getter
double get area {
return 3.141592653589793 * pow(radius, 2)
}
}
void main() {
var circle = Circle(5);
print(circle.circumference); // 31.41592653589793 출력
}
위의 코드에서 circumference
는 getter로 정의되어 있으며, 이를 통해 원의 둘레를 계산하여 반환합니다. main
함수에서는 circle.circumference
처럼 메서드가 아닌 속성처럼 접근하여 값을 얻을 수 있습니다.
Setter는 객체의 속성값을 설정하는 메서드입니다. Dart에서는 set
키워드를 사용하여 setter를 정의할 수 있습니다.
class Circle {
double radius;
Circle(this.radius);
// 원의 지름을 설정하는 setter
set diameter(double diameter) {
radius = diameter / 2;
}
}
void main() {
var circle = Circle(5);
print(circle.radius); // 5.0 출력
circle.diameter = 10;
print(circle.radius); // 5.0 출력
}
위의 코드에서 diameter
는 setter로 정의되어 있으며, 이를 통해 원의 지름을 설정할 수 있습니다. main
함수에서는 circle.diameter = 10;
처럼 속성처럼 접근하여 값을 설정합니다. 이때 내부적으로는 diameter
setter가 호출되며, radius
값이 10의 반인 5로 설정됩니다.
불변성(immutability)을 유지하는 프로그래밍 패러다임은 많은 현대 프로그래밍 언어와 프레임워크에서 선호되고 있습니다. 불변 객체는 한 번 생성되면 그 상태를 변경할 수 없습니다. 이러한 특성 덕분에 불변 객체는 프로그램의 복잡성을 줄이고, 버그를 예방하며, 여러 스레드 간의 안전한 데이터 공유를 가능하게 합니다.
Dart와 같은 언어에서는 final
키워드를 사용하여 불변 변수를 선언할 수 있으며, 이는 객체의 상태가 생성 후에 변경되지 않도록 보장합니다.
Setter 메서드는 객체의 상태를 변경할 수 있기 때문에, 불변성을 유지하려는 프로그래밍 스타일과는 상충될 수 있습니다. 따라서 불변성을 지향하는 프로그래밍에서는 setter의 사용을 피하고, 필요할 경우 객체 전체를 새로 생성하는 방식을 선호합니다.
예를 들어, 다음과 같이 불변 클래스를 정의할 수 있습니다:
class Point {
final double x;
final double y;
const Point(this.x, this.y);
Point copyWith({double? x, double? y}) {
return Point(x ?? this.x, y ?? this.y);
}
}
위의 Point
클래스는 불변이며, 상태를 변경하고 싶을 때는 copyWith
메서드를 사용하여 새로운 Point
객체를 생성합니다. 이 방식은 객체의 상태가 일관되게 유지되도록 돕고, 프로그램의 예측 가능성을 향상시킵니다.
Dart에서 setter 메서드는 반드시 한 개의 매개변수만 가질 수 있습니다. 이것은 setter가 변수에 값을 할당하는 것처럼 작동하기 때문입니다. 즉, 다음과 같이 사용할 수 있습니다:
class MyClass {
int _value = 0;
void set value(int newValue) {
_value = newValue;
}
int get value => _value;
}
void main() {
var myObject = MyClass();
myObject.value = 10; // 여기에서 setter를 호출합니다.
print(myObject.value); // 출력: 10
}
위 예제에서 value
setter는 정확히 한 개의 매개변수 newValue
를 가지고 있습니다. 이것은 Dart의 규칙이며, 이를 통해 개발자는 객체의 특정 속성에 값을 할당하는 것처럼 setter를 사용할 수 있습니다.
만약 여러 값을 설정해야 한다면, 여러 개의 setter를 정의하거나, 다른 메서드를 사용해야 합니다. 또는 객체를 불변으로 만들고 copyWith
같은 패턴을 사용하는 것도 좋은 방법입니다.
Getter와 setter를 사용하면 객체의 속성에 대한 접근과 수정을 더 세밀하게 제어할 수 있습니다. 이를 통해 객체의 내부 상태를 보호하고, 필요한 계산을 수행하며, 입력값의 유효성을 검사할 수 있습니다.