[Dart] Flutter에서 extends, mixin, implements의 차이와 활용

Noah·2025년 5월 2일
0

Flutter

목록 보기
10/11

Flutter는 Dart 언어를 기반으로 하며, 객체지향 프로그래밍(OOP) 개념을 바탕으로 클래스 상속 구조를 지원한다. 이 글에서는 Dart에서 클래스 간 상속과 재사용을 위한 주요 키워드인 extends, with, implements에 대해 정리하고, 각각의 차이점을 비교해본다.


1. extends - 클래스 상속 (단일 상속)

extends는 한 클래스가 다른 클래스의 기능을 상속받고, 필요에 따라 오버라이드할 수 있게 해준다. Dart는 단일 상속만 지원하기 때문에, 한 번에 하나의 클래스만 상속 가능하다.

class Animal {
  void sound() => print("Some sound");
}

class Dog extends Animal {
  
  void sound() => print("Bark");
}

특징

  • 부모 클래스의 속성과 메서드를 그대로 가져온다.
  • super 키워드로 부모 클래스의 기능에 접근할 수 있다.
  • 생성자도 상속 대상이며, 명시적으로 호출해야 한다.

2. with - 믹스인(Mixin)

with는 코드 재사용을 위한 방식으로, 여러 클래스의 기능을 조합해서 사용할 수 있다. 다중 믹스인을 허용하기 때문에 복수의 클래스로부터 메서드와 속성을 가져올 수 있다.

mixin CanSwim {
  void swim() => print("Swimming");
}

mixin CanRun {
  void run() => print("Running");
}

class Human with CanSwim, CanRun {}

특징

  • 여러 믹스인을 한 클래스에 동시에 적용할 수 있다.
  • 믹스인은 상태(state)를 가질 수 있다.
  • 생성자를 정의할 수 없으며, 정의하면 에러가 발생한다.
  • mixin, 또는 믹스인으로 사용할 수 있는 클래스에만 with를 사용할 수 있다.

3. 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는 어떤 클래스나 인터페이스의 구조만 따르되, 로직은 모두 직접 정의해야 할 때 선택한다.

각 키워드의 목적이 뚜렷하니, 상황에 맞게 적절히 선택해서 사용하는 게 중요하다.

profile
Flutter Specialist

0개의 댓글