개발
Dart Extension (확장 메서드) 정리
오늘도멋진하루
2025. 4. 18. 03:00
Dart의 Extension(확장 메서드)는 기존 클래스의 기능을 확장하여 새로운 메서드나 속성을 추가할 수 있도록 합니다.
이것은 원래 클래스를 수정하거나 상속받지 않고도, 기존 클래스에 새로운 기능을 추가하는 강력한 도구입니다.
특히 제어할 수 없는 클래스 (예: 라이브러리의 클래스)에 유용합니다.
목차
기본 동작
확장 메서드는 extension
키워드와 이름을 통해 선언되며, 특정 타입에 새로운 메서드 또는 속성을 추가할 수 있습니다.
예제: 문자열 뒤집기
extension StringExtension on String {
String get reversed => split('').reversed.join(); // 문자열 뒤집기
}
void main() {
var word = 'Dart';
print(word.reversed); // 출력: traD
}
동작 원리:
extension [이름] on [타입]
을 사용하여 타입(String
)에 기능을 추가.get
키워드를 사용해 읽기 전용 속성을 정의.- 확장된 속성과 메서드는 원래의
String
클래스 객체에서 직접 사용 가능.
확장 메서드의 장점
- 원본 클래스 수정 필요 없음
- 원래의 클래스를 유지하면서 새로운 메서드만 추가.
- 읽기 전용 상태로 유지
- 확장 메서드는 기존 상태를 바꾸지 않고, 기존 데이터를 기반으로 새로운 데이터를 반환.
- 재사용성 높음
- 공통적으로 많이 사용되는 기능을 쉽게 확장.
확장 메서드와 함수의 차이점
확장 메서드는 확장하고자 하는 객체의 메서드처럼 작동하지만, 독립적인 함수와의 차이가 있습니다.
예제: 독립 함수와 확장 메서드 비교
// 독립 함수
String reverseString(String value) {
return value.split('').reversed.join();
}
// 확장 메서드
extension StringExtension on String {
String get reversed => split('').reversed.join();
}
void main() {
// 독립 함수 사용
print(reverseString('Dart')); // 출력: traD
// 확장 메서드 사용
print('Dart'.reversed); // 출력: traD
}
주요 차이점:
독립 함수 | 확장 메서드 |
---|---|
호출 시 객체가 필요 없음 | 객체 인스턴스에서 바로 호출 가능 |
유연하게 모든 타입 활용 가능 | 특정 타입에 종속적 |
메서드와 속성 추가
확장 메서드는 메서드뿐만 아니라 속성도 추가할 수 있습니다.
속성 추가 예제
extension NumberExtension on int {
bool get isEven => this % 2 == 0; // 짝수 여부 확인
bool get isOdd => !isEven; // 홀수 여부 확인
int times(int multiplier) => this * multiplier; // 곱하기
}
void main() {
int num = 4;
print(num.isEven); // 출력: true
print(num.isOdd); // 출력: false
print(num.times(3)); // 출력: 12
}
네임스페이스 충돌 해결
여러 확장 메서드가 동일한 메서드 이름을 정의할 경우, 가장 가까운 범위의 확장이 우선 적용됩니다.
네임스페이스 충돌 예제
extension ExtensionA on String {
String get fancyName => 'ExtensionA: $this';
}
extension ExtensionB on String {
String get fancyName => 'ExtensionB: $this';
}
void main() {
String name = 'Dart';
// 가장 가까운 확장 사용
print(name.fancyName); // 출력: ExtensionB: Dart
}
- 위에서
ExtensionB
가 더 가까이 있기 때문에 적용됩니다. - 특정 확장을 명시적으로 사용하려면 확장을 함수처럼 호출할 수 있습니다.
void main() {
String name = 'Dart';
print(ExtensionA(name).fancyName); // 출력: ExtensionA: Dart
}
제네릭 확장
Dart의 확장은 제네릭으로도 사용할 수 있습니다.
예제: 제네릭 확장
extension ListExtension<T> on List<T> {
void printAll() {
forEach((element) => print(element));
}
}
void main() {
var intList = [1, 2, 3];
var stringList = ['Dart', 'Flutter'];
intList.printAll();
stringList.printAll();
}
결과:
1
2
3
Dart
Flutter
제한 사항
- 기존 클래스의 필드, 메서드에 접근 불가
- 확장 메서드는 원래 클래스의 private 멤버(
_로 시작하는 필드와 메서드
)에 접근할 수 없습니다.
- 확장 메서드는 원래 클래스의 private 멤버(
- 상속 관계 아님
- 확장 메서드는 원본 클래스의 서브클래스가 아니며, 타입을 변경하지 않습니다.
- 메서드 오버라이딩 불가능
- 확장 메서드는 원본 클래스의 메서드를 재정의하지 못합니다.
활용 사례
확장 메서드는 특히 다음과 같은 경우에 유용합니다:
- 자주 쓰는 유틸리티 함수 추가
- 날짜, 문자열, 숫자 변환 등.
- 코드 가독성 향상
- 객체의 속성을 확인하거나 메서드를 호출하는 코드를 간결하게 작성.
- 라이브러리 확장
- 외부 라이브러리 클래스에 사용자가 정의한 새로운 메서드 추가.
확장 메서드는 기존 클래스를 수정하지 않고도 코드의 유연성과 유지보수성을 크게 향상시킬 수 있습니다.