본문 바로가기
Flutter/개념

Dart 기본기 - Dart 3.0 클래스

by 윤숩 2025. 2. 5.
728x90
728x90

1. final class 기본 개념

▪️클래스의 확장(상속) 제한

     - final class를 사용하면 다른 클래스가 해당 클래스를 상속하여 기능을 변경하는 것을 방지할 수 있음.

     - extends, implement, 또는 mixin으로 사용이 불가능 

▪️ 보안성 및 안정성 증가

      - 라이브러리나 패키지를 만들 때 외부에서 임의로 상속하여 오작동하는 것을 방지할 수 있음.

▪️ 불필요한 상속 구조 제거

       - 특정 클래스가 상속을 필요로 하지 않는 경우 final class를 사용하여 명확한 설계를 유도할 수 있음.

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

// ❌ 오류 발생: final class는 상속할 수 없음
class Dog extends Animal {
  void bark() => print("Woof!");
}

void main() {
  Animal().makeSound();
}


// => Error: The class 'Animal' can't be extended because it's final.

 

  • final class Animal은 Dog이 상속할 수 없음.
  • 인스턴스화(객체 생성)는 가능하지만, 확장은 불가능.

2. base class 기본 개념

▪️ 강제적인 상속 규칙 유지

     - 특정 클래스를 상속할 수 있지만, 반드시 base 키워드를 사용하도록 제한하여 예측 가능한 구조 유지.

     => extends는 가능하지만 implement는 불가능

▪️ 라이브러리 및 패키지에서 상속 방식 제한

      - Dart 라이브러리 개발 시, API를 설계할 때 무분별한 상속을 방지하면서도 상속 가능성을 유지할 수 있음.

▪️ 안정적인 상속 구조 제공

       - base를 사용하면 다른 개발자가 클래스의 상속 구조를 변경하는 것을 방지하면서도, 확장 가능한 방식으로 설계를 유지할 수 있습니다. 

 

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

// ✅ 올바른 상속 (같은 파일 또는 다른 파일에서도 base 키워드를 사용해야 함)
base class Dog extends Animal {
  void bark() => print("Woof!");
}

void main() {
  Dog dog = Dog();
  dog.makeSound(); // Animal sound
  dog.bark(); // Woof!
}


// => Error: The class 'Dog' must be 'base' because it extends 'Animal'.

 

 

 

 

  • base class Animal을 상속하려면 base 키워드를 필수적으로 사용해야 함.
  • class Dog extends Animal {} 형태로 선언하면 오류 발생.

3. interface class 기본 개념

Dart에서 interface는 클래스가 특정 메서드와 프로퍼티를 반드시 구현하도록 강제하는 역할을 합니다.

Dart에는 interface 키워드가 없지만, 모든 클래스는 자동으로 인터페이스 역할을 할 수 있습니다.

즉, Dart에서는 일반 클래스도 인터페이스처럼 사용 가능하며, implements 키워드를 사용하여 인터페이스를 구현할 수 있습니다.

 

 

  • implements 키워드를 사용하여 인터페이스를 구현할 수 있음.
  • 인터페이스를 구현하는 클래스는 반드시 모든 메서드를 재정의(override)해야 함.
  • 다중 인터페이스 구현 가능 (여러 개의 클래스를 implements로 동시에 사용할 수 있음).
class Animal {
  void makeSound() => print("Some animal sound");
}

// ✅ Animal을 인터페이스로 사용
class Dog implements Animal {
  @override
  void makeSound() {
    print("Woof!");
  }
}

void main() {
  Dog dog = Dog();
  dog.makeSound(); // Woof!
}



// Dart 3.0
interface class Vehicle {
  void move();
}

// ✅ 모든 메서드를 반드시 재정의해야 함
class Car implements Vehicle {
  @override
  void move() {
    print("Car is moving");
  }
}

void main() {
  Car car = Car();
  car.move(); // Car is moving
}

 

  • Dog 클래스는 Animal의 모든 메서드를 반드시 재정의해야 함.

4. abstract class 기본 개념

Dart에서는 abstract class를 활용하여 인터페이스를 명확하게 정의할 수 있습니다.

 

abstract class Animal {
  void makeSound(); // 추상 메서드 (구현 필요)
}

// ✅ Animal 인터페이스 구현
class Cat implements Animal {
  @override
  void makeSound() {
    print("Meow!");
  }
}

void main() {
  Cat cat = Cat();
  cat.makeSound(); // Meow!
}

 

 

  • abstract class Animal을 인터페이스처럼 활용.
  • Cat 클래스는 makeSound()를 반드시 구현해야 함.

 

 

 


5. sealed class 기본 개념

Dart 3.0에서 도입된 sealed class는 같은 파일 내에서만 상속할 수 있는 클래스입니다.
즉, 다른 파일에서는 sealed class를 상속할 수 없으며, 상속을 허용하면서도 제한적인 확장을 제공하는 기능입니다.

 

sealed class Animal {} // ✅ sealed class 선언

// ✅ 같은 파일 내에서만 상속 가능
class Dog extends Animal {}
class Cat extends Animal {}

// ❌ 다른 파일에서는 상속할 수 없음!



// switch 문 예제
sealed class PaymentMethod {}

class CreditCard extends PaymentMethod {}
class PayPal extends PaymentMethod {}
class BankTransfer extends PaymentMethod {}

void processPayment(PaymentMethod payment) {
  switch (payment) {
    case CreditCard():
      print("Processing credit card payment");
    case PayPal():
      print("Processing PayPal payment");
    case BankTransfer():
      print("Processing bank transfer payment");
  }
}

void main() {
  processPayment(CreditCard()); // Processing credit card payment
}

 

 

  • sealed class는 같은 파일 내에서만 상속 가능. (하위 클래스는 제한적, switch문과 함께 사용하기 좋)
  • 다른 파일에서는 상속이 불가능, 즉, 특정 파일 안에서만 클래스를 확장할 수 있도록 제한.
  • sealed class를 사용하면 switch 문에서 모든 하위 클래스를 체크해야 하므로, 새로운 하위 클래스가 추가될 경우 컴파일러가 자동으로 누락된 case를 감지할 수 있음.

6. mixin class 기본 개념

Dart에서 mixin은 코드를 여러 클래스에서 재사용할 수 있도록 하는 기능입니다.
mixin을 사용하면 클래스를 상속하지 않고도 특정 기능을 여러 클래스에서 공유할 수 있습니다.

 

 

  • mixin은 클래스를 상속하지 않고 기능을 공유하는 방법입니다.
  • with 키워드를 사용하여 mixin을 적용할 수 있습니다.
  • 다중 상속이 불가능한 Dart에서 mixin을 활용하면 코드 중복 없이 여러 클래스에서 같은 기능을 사용할 수 있습니다.
mixin Logger {
  void log(String message) {
    print("LOG: $message");
  }
}

class Service with Logger {
  void fetchData() {
    log("Fetching data...");
  }
}

void main() {
  Service service = Service();
  service.fetchData(); // LOG: Fetching data...
}


// 다중 적용
mixin Logger {
  void log(String message) => print("LOG: $message");
}

mixin Validator {
  bool isValid(String input) => input.isNotEmpty;
}

class Service with Logger, Validator {
  void fetchData(String data) {
    if (isValid(data)) {
      log("Fetching data: $data");
    } else {
      log("Invalid data");
    }
  }
}

void main() {
  Service service = Service();
  service.fetchData("Hello"); // ✅ LOG: Fetching data: Hello
  service.fetchData(""); // ✅ LOG: Invalid data
}

 

 

 

 

  • mixin Logger를 정의하고 log 메서드를 포함.
  • Service 클래스에서 Logger를 with 키워드로 포함.
  • Service 클래스에서 log 메서드를 사용하여 로깅 기능을 추가.

 

 


키워드 설명 상속 가능 여부
sealed class 같은 파일 내에서만 상속 가능 ✅ 같은 파일 내에서만 가능
final class 어디서든 상속 불가능 ❌ 상속 불가능
base class 다른 파일에서도 상속 가능하지만, base 키워드가 필요 ✅ base 키워드 사용 시 가능
728x90
728x90

댓글