Dart - Class Modifier
Dart 3부터 클래스 선언에 사용할 수 있는 다양한 modifier가 도입되며, 코드 설계의 유연성과 안정성이 크게 향상되었습니다.
하지만 abstract, base, interface, final, sealed, mixin 등 다양한 키워드들이 존재하다 보니, 언제 어떤 걸 써야 하는지 헷갈릴 수 있죠.
이 글에서는 Dart 공식 문서 기준으로 각 modifier의 역할, 적절한 사용 시점, 간단한 예제를 통해 알아 보도록 하겠습니다.
https://dart.dev/language/modifier-reference
Modifier 요약 표
Modifier | 생성자 | extends | implements | mixin | 특징 |
abstract final class | ❌ | ❌ | ❌ | ❌ | ❌ |
class | ✅ | ✅ | ✅ | ❌ | 기본 클래스 |
abstract class | ❌ | ✅ | ✅ | ❌ | 추상 클래스 |
interface class | ✅ | ❌ | ✅ | ❌ | 인터페이스 전용 |
abstract interface class | ❌ | ❌ | ✅ | ❌ | 순수 인터페이스 |
base class | ✅ | ✅ | ❌ | ❌ | 상속만 허용 |
abstract base class | ❌ | ✅ | ❌ | ❌ | 추상 + 상속만 허용 |
final class | ✅ | ❌ | ❌ | ❌ | 봉인된 클래스 |
sealed class | ❌ | ❌ | ❌ | ❌ | 패턴 매칭 제한 클래스 |
mixin | ❌ | ❌ | ✅ | ✅ | 기능 믹스인 |
mixin class | ✅ | ❌ | ❌ | ✅ | mixin + class |
abstract mixin class | ❌ | ✅ | ✅ | ✅ | 추상 + 믹스인 |
base mixin | ❌ | ❌ | ❌ | ✅ | 제한된 믹스인 |
base mixin class | ✅ | ✅ | ❌ | ✅ | mixin 전용 base |
Class
class Animal {
void sound() => print('Animal sound');
}
class Dog extends Animal {}
class Cat implements Animal {
@override
void sound() => print('Meow');
}
void main() {
Animal a = Dog();
a.sound(); // Animal sound
Animal c = Cat();
c.sound(); // Meow
}
- 인스턴스화
- extends
- implements
abstract class
- extends
- implements
- default 메서드
abstract class Animal {
void sound();
void eat() => print('Eating');
}
class Dog extends Animal {
@override
void sound() => print('Bark');
}
void main() {
Animal a = Dog();
a.sound();
a.eat();
}
base class
base class BaseAnimal {
void sound() => print('Base sound');
}
class MyDog extends BaseAnimal {}
- extends
- 생성자
interface class
interface class Logger {
void log(String msg) {
print('LOG: $msg');
}
}
class MyLogger implements Logger {
@override
void log(String msg) {
print('Custom log: $msg');
}
}
- 여전히 클래스이기 때문에 default 메서드 구현 필수
- implements
- 생성자
abstract interface class
abstract interface class Shape {
double getArea();
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
@override
double getArea() => 3.14 * radius * radius;
}
- defualt method
- implements
final class
final class Utils {
void printHello() => print('Hello');
}
// 에러 발생
class MyUtils extends Utils {}
- 확장, 구현, 믹스인 금지
- 인스턴스화 가능
sealed class
sealed class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
void printAnimal(Animal a) {
switch (a) {
case Dog():
print('Dog!');
case Cat():
print('Cat!');
}
}
- 외부에서 상속 불가
- switch 문에서 exhaustiveness 보장
mixin class
mixin class Logger {
void log(String msg) => print('LOG: $msg');
}
class Service with Logger {}
class MyLogger extends Logger {}
- mixin 으로도, class 로도 사용 가능
- on 사용 불가
base mixin class
base mixin class Printer {
void printMessage(String msg) => print(msg);
}
class PrinterUser with Printer {}
//불가능
class PrinterMock implements Printer {}
- implements 금지
- mixin, extends 허용
abstract mixin class
abstract mixin class Musician {
void playInstrument(String name);
void playPiano() => playInstrument('Piano');
}
class Pianist with Musician {
@override
void playInstrument(String name) {
print('Playing $name');
}
}
- default 메서드 허용
- mixin 및 extends/implements 가능
abstract base mixin class
abstract base mixin class Notifier {
void notify(String msg);
}
class MyNotifier with Notifier {
@override
void notify(String msg) => print('Notify: $msg');
}
// 금지
class Mock implements Notifier {}
- mixin, extends 허용
- implements 금지
- 추상 선언 가능
mixin
mixin Greeter {
void sayHi() => print('Hi!');
}
class Person with Greeter {}
- with, implements 사용 가능
- 인스턴스화 불가
base mixin
base mixin Runner {
void run() => print('Running');
}
class Athlete with Runner {}
// 불가
class Test implements Runner {}
- 오직 mixin으로만 사용 가능
금지된 조합
Dart에서는 일부 모디파이어 조합이 문법적으로 허용되지 않습니다.
이를 사용하면 컴파일 에러가 발생합니다.
base, interface, final 간 조합
이 세 가지는 서로 독립적인 목적을 갖기 때문에 한 클래스 선언에 동시에 사용할 수 없습니다.
// Error: 'interface' and 'base' can't be combined
base interface class A {}
- base → 상속만 허용
- interface → 구현만 허용
- final → 상속, 구현 모두 금지
목적이 상충되므로 동시에 사용할 수 없음.
sealed와 다른 제한자들
sealed는 하위 타입을 라이브러리 내부로 제한하기 때문에 다음과 같은 조합도 불가합니다.
// Error: sealed class can't be final or interface
sealed final class B {}
- sealed는 상속 제한 + 패턴 매칭 exhaustive 지원
- final이나 interface와 의미 충돌
mixin 관련 금지 조합
mixin 또는 mixin class 선언에서는 다음과 같은 제한이 있습니다:
선언 타입사용 금지 키워드
mixin | abstract, base, final, sealed, interface |
mixin class | interface, final, sealed |
base mixin | interface, final, abstract 등 |
'Flutter' 카테고리의 다른 글
Vercel - Web 배포 (0) | 2025.08.05 |
---|---|
Flutter - extends, implements, with, mixin (0) | 2024.04.30 |