extends
와 with
Dart 언어에서 클래스를 구성하는 두 가지 다른 방법입니다. 이 두 키워드의 주요 차이점은 상속과 믹스인(mixin)의 차이에 기인합니다.
extends
Dart에서 extends
키워드는 한 클래스가 다른 클래스로부터 상속을 받을 때 사용됩니다. Dart에서 클래스는 단일 상속만 지원하므로 클래스는 하나의 부모 클래스만 가질 수 있습니다. 이는 기본 클래스의 모든 속성과 메소드를 자식 클래스가 상속받게 하며, 추가적으로 메소드를 재정의(override)할 수도 있습니다.
class Animal {
void breathe() => print('Breathing...');
}
class Dog extends Animal {
void wagTail() => print('Wagging tail...');
}
void main() {
var dog = Dog();
dog.breathe(); // 출력: Breathing...
dog.wagTail(); // 출력: Wagging tail...
}
with
반면에 with
키워드는 믹스인(mixin)을 사용하기 위해 사용됩니다. 믹스인은 클래스가 다른 클래스의 코드를 재사용하는 방법 중 하나입니다. 즉, Dog 클래스는 Carnivore와 Swimmer의 메서드를 사용할 수 있지만 Carnivore와 Swimmer의 서브클래스가 아닙니다.
믹스인은 단일 상속 언어에서 다중 상속과 유사한 효과를 얻을 수 있습니다. 이를 통해 클래스는 여러 다른 클래스로부터 메소드를 상속받습니다.
Dart에서는 다중 상속을 지원하지 않기 때문에, 이렇게 믹스인을 사용하여 여러 클래스의 기능을 조합할 수 있습니다.
예제
mixin Carnivore {
void eatMeat() => print('Eating meat...');
}
mixin Swimmer {
void swim() => print('Swimming...');
}
class Dog with Carnivore, Swimmer {
void bark() => print('Barking...');
}
void main() {
var dog = Dog();
dog.eatMeat(); // 출력: Eating meat...
dog.swim(); // 출력: Swimming...
dog.bark(); // 출력: Barking...
}
Dart 언어에서는 mixin 키워드를 사용해 명시적으로 믹스인을 정의하도록 권장하고 있습니다.
Dart 2.1 이전에는 class 키워드를 사용해 믹스인을 생성할 수 있었지만, 이러한 방식은 여러 가지 제한사항을 가지고 있었습니다. Dart 2.1에서 mixin 키워드가 도입되면서 믹스인을 더 명확하고 안전하게 사용할 수 있게 되었습니다.
그러나 여전히 일반 클래스를 믹스인으로 사용하는 것이 가능한 경우도 있습니다.
클래스가 아래의 조건을 모두 만족하면 믹스인으로 사용할 수 있습니다:
클래스가 Object를 직접 상속하고 있어야 합니다. 즉, 다른 클래스를 상속하고 있으면 안됩니다.
클래스에 선언된 생성자가 없어야 합니다.
이렇게 일반 클래스를 믹스인으로 사용하는 방식은 믹스인의 복잡성을 증가시키므로, 대부분의 경우 mixin 키워드를 사용하여 믹스인을 명확하게 정의하는 것이 좋습니다.