Getters & Setters 심화
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 33번째.
게터(getters)와 세터(setters)는 프라이빗 필드와 결합될 때 캡슐화를 위한 강력한 도구가 됩니다. 이를 통해 데이터가 액세스되고 수정되는 방식에 대한 완전한 제어를 유지하면서 깔끔한 공개 인터페이스를 노출할 수 있습니다.
일반적인 패턴은 프라이빗 필드를 퍼블릭 게터(getter) 및 유효성 검사가 포함된 세터(setter)와 결합하는 것입니다:
class Temperature {
double _celsius = 0;
double get celsius => _celsius;
set celsius(double value) {
if (value < -273.15) {
_celsius = -273.15; // Absolute zero minimum
} else {
_celsius = value;
}
}
}세터는 비즈니스 규칙을 강제하여 객체가 유효하지 않은 상태가 되지 않도록 보장할 수 있습니다.
또한 프라이빗 데이터로부터 값을 도출하는 계산된 게터(computed getters)를 생성할 수도 있습니다:
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height; // 계산됨
double get perimeter => 2 * (_width + _height);
double get width => _width;
set width(double value) {
if (value > 0) _width = value;
}
}때로는 읽기 전용 액세스를 원할 때가 있습니다. 세터(setter) 없이 게터(getter)만 제공하면 됩니다:
class Order {
final DateTime _createdAt = DateTime.now();
DateTime get createdAt => _createdAt; // 읽기 전용
}이 패턴은 외부 코드에 데이터에 대한 가시성을 제공하면서 어떠한 수정도 방지합니다. getter만 결합된 private 필드는 진정한 읽기 전용 액세스를 생성합니다.
챌린지
쉬움데이터 액세스를 제어하기 위한 getter와 setter의 강력함을 보여주는 제품 인벤토리 시스템을 구축해 보겠습니다. 내부 데이터를 보호하면서 계산된 속성과 유효성 검사를 제공하는 클래스를 만들게 됩니다.
코드를 두 개의 파일로 구성합니다:
product.dart: 적절한 캡슐화를 통해 인벤토리를 관리하는Product클래스를 정의합니다. 제품은 다음을 포함해야 합니다:- 공개(public)
String name - 비공개(private)
double _price - 비공개(private)
int _quantity - 세 가지 값을 모두 받는 생성자
- 비공개 가격을 반환하는 getter
price 0보다 큰 값만 허용하는 setterprice(유효하지 않은 값은 무시)- 비공개 수량을 반환하는 getter
quantity 0이상의 값만 허용하는 setterquantity(음수 값은 무시)_price * _quantity를 반환하는 계산된 gettertotalValue- 수량이
0보다 크면true를 반환하는 계산된 getterisInStock - 이름의 처음 3글자를 대문자로 변환한 뒤 수량을 붙여 간단한 SKU를 생성하는 읽기 전용 getter
sku(예: 수량이 25인 "Laptop"의 경우LAP25) - 제품 상세 정보를 보여주는 메서드
displayProduct()
- 공개(public)
main.dart: 제품 클래스를 임포트하고 getter와 setter가 액세스를 어떻게 제어하는지 보여줍니다:- 이름이
'Laptop'이고 가격이999.99, 수량이25인 제품을 생성합니다. displayProduct()를 호출합니다.In stock: [isInStock]을 출력합니다.SKU: [sku]를 출력합니다.- 가격을
-50.0으로 설정을 시도합니다 (무시되어야 함). - 가격을
899.99로 설정합니다 (유효한 변경). - 수량을
-10으로 설정을 시도합니다 (무시되어야 함). - 수량을
0으로 설정합니다 (유효한 변경). displayProduct()를 호출합니다.In stock: [isInStock]을 출력합니다.SKU: [sku]를 출력합니다.
- 이름이
displayProduct() 메서드는 다음 형식으로 출력해야 합니다:
--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]예상 출력 결과:
--- Product Info ---
Name: Laptop
Price: $999.99
Quantity: 25
Total Value: $24999.75
In stock: true
SKU: LAP25
--- Product Info ---
Name: Laptop
Price: $899.99
Quantity: 0
Total Value: $0.0
In stock: false
SKU: LAP0치트 시트
Getter와 setter를 프라이빗 필드와 결합하면 캡슐화와 데이터 접근 제어를 제공할 수 있습니다.
Getter와 Setter가 있는 프라이빗 필드
class Temperature {
double _celsius = 0;
double get celsius => _celsius;
set celsius(double value) {
if (value < -273.15) {
_celsius = -273.15;
} else {
_celsius = value;
}
}
}계산된 Getter
Getter는 프라이빗 데이터로부터 값을 파생시킬 수 있습니다:
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height;
double get perimeter => 2 * (_width + _height);
double get width => _width;
set width(double value) {
if (value > 0) _width = value;
}
}읽기 전용 접근
읽기 전용 속성을 위해 setter 없이 getter만 제공합니다:
class Order {
final DateTime _createdAt = DateTime.now();
DateTime get createdAt => _createdAt;
}직접 해보기
import 'product.dart';
void main() {
// TODO: 가격이 999.99이고 수량이 25인 'Laptop'이라는 이름의 제품을 생성하세요.
// TODO: displayProduct()를 호출하세요.
// TODO: "In stock: [isInStock]"을 출력하세요.
// TODO: "SKU: [sku]"를 출력하세요.
// TODO: 가격을 -50.0으로 설정을 시도하세요 (무시되어야 함).
// TODO: 가격을 899.99로 설정하세요 (유효한 변경).
// TODO: 수량을 -10으로 설정을 시도하세요 (무시되어야 함).
// TODO: 수량을 0으로 설정하세요 (유효한 변경).
// TODO: displayProduct()를 호출하세요.
// TODO: "In stock: [isInStock]"을 출력하세요.
// TODO: "SKU: [sku]"를 출력하세요.
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.