Flutter는 Dart 언어를 기반으로 하며, 객체지향 프로그래밍(OOP) 개념을 바탕으로 클래스 상속 구조를 지원한다. 이 글에서는 Dart에서 클래스 간 상속과 재사용을 위한 주요 키워드인
extends,with,implements에 대해 정리하고, 각각의 차이점을 비교해본다.
extends - 클래스 상속 (단일 상속)extends는 한 클래스가 다른 클래스의 기능을 상속받고, 필요에 따라 오버라이드할 수 있게 해준다. Dart는 단일 상속만 지원하기 때문에, 한 번에 하나의 클래스만 상속 가능하다.
class Animal {
void sound() => print("Some sound");
}
class Dog extends Animal {
void sound() => print("Bark");
}
특징
super 키워드로 부모 클래스의 기능에 접근할 수 있다.with - 믹스인(Mixin)with는 코드 재사용을 위한 방식으로, 여러 클래스의 기능을 조합해서 사용할 수 있다. 다중 믹스인을 허용하기 때문에 복수의 클래스로부터 메서드와 속성을 가져올 수 있다.
mixin CanSwim {
void swim() => print("Swimming");
}
mixin CanRun {
void run() => print("Running");
}
class Human with CanSwim, CanRun {}
특징
mixin, 또는 믹스인으로 사용할 수 있는 클래스에만 with를 사용할 수 있다.implements - 인터페이스 구현implements는 특정 클래스나 믹스인의 구조만 가져오고, 그 안의 모든 메서드와 속성을 반드시 직접 구현해야 한다. 원본 클래스의 구현은 전혀 사용하지 않는다.
class Flyer {
void fly() {}
}
class Bird implements Flyer {
void fly() => print("Flying");
}
특징
| 구분 | 키워드 | 다중 적용 | 메서드 재사용 | 메서드 재정의 필수 | 생성자 상속 |
|---|---|---|---|---|---|
| 상속 | extends | ❌ | ✅ | ❌ (선택적) | ✅ |
| 믹스인 | with | ✅ | ✅ | ❌ (선택적) | ❌ |
| 인터페이스 구현 | implements | ✅ | ❌ | ✅ (필수) | ❌ |
// 부모 클래스: Animal
abstract class Animal {
void makeSound();
}
// 믹스인: 수영하는 능력
mixin Swimmer {
void swim() => print('수영 중 🏊♀️');
}
// 인터페이스로 사용될 클래스
class Flyer {
void fly() {} // 인터페이스처럼 사용
}
// extends 사용: Dog는 Animal의 기능을 상속
class Dog extends Animal {
void makeSound() => print('멍멍 🐶');
}
// extends + with 사용: Duck은 Animal을 상속하고 Swimmer 믹스인 추가
class Duck extends Animal with Swimmer {
void makeSound() => print('꽥꽥 🦆');
}
// implements 사용: Airplane은 Flyer 인터페이스 구현
class Airplane implements Flyer {
void fly() => print('비행기 이륙 중 ✈️');
}
// extends + with + implements 조합
class FlyingFish extends Animal with Swimmer implements Flyer {
void makeSound() => print('촤르르... 🐟');
void fly() => print('물 위로 잠깐 비행!');
}
// 테스트 실행용 main 함수
void main() {
final dog = Dog();
dog.makeSound(); // 멍멍 🐶
final duck = Duck();
duck.makeSound(); // 꽥꽥 🦆
duck.swim(); // 수영 중 🏊♀️
final airplane = Airplane();
airplane.fly(); // 비행기 이륙 중 ✈️
final flyingFish = FlyingFish();
flyingFish.makeSound(); // 촤르르... 🐟
flyingFish.swim(); // 수영 중 🏊♀️
flyingFish.fly(); // 물 위로 잠깐 비행!
}
extends는 부모 클래스의 기능을 확장하거나 재정의하고 싶을 때 사용한다.with은 여러 기능을 하나의 클래스에 조합해서 재사용하고 싶을 때 쓰인다.implements는 어떤 클래스나 인터페이스의 구조만 따르되, 로직은 모두 직접 정의해야 할 때 선택한다.각 키워드의 목적이 뚜렷하니, 상황에 맞게 적절히 선택해서 사용하는 게 중요하다.