본문 바로가기
Programming/Dart

Dart Inheritance

by #root 2025. 3. 25.

Dart 상속(Inheritance) 개념 및 예제

1. 상속(Inheritance)이란?

상속이란 **부모 클래스(슈퍼 클래스)**의 속성과 메서드를 **자식 클래스(서브 클래스)**에서 재사용하는 개념입니다.
Dart에서는 extends 키워드를 사용하여 클래스를 상속받을 수 있습니다.

📌 상속을 사용하는 이유

  • 코드 재사용성 향상
  • 유지보수 용이
  • 객체 지향 프로그래밍(OOP) 원칙 준수

2. Dart에서 상속 기본 문법

Dart에서 클래스 상속은 extends 키워드를 사용합니다.

class 부모클래스 {
  // 속성과 메서드 정의
}

class 자식클래스 extends 부모클래스 {
  // 추가적인 속성과 메서드 정의 가능
}​

3. 상속 예제 (기본)

📌 부모 클래스(Superclass)

class Animal {
  String name;
  int age;

  Animal(this.name, this.age);

  void makeSound() {
    print('동물이 소리를 냅니다.');
  }
}​
 

📌 자식 클래스(Subclass)에서 상속받기

 
class Dog extends Animal {
  String breed;

  Dog(String name, int age, this.breed) : super(name, age);

  // 메서드 오버라이딩 (부모 클래스의 메서드를 재정의)
  @override
  void makeSound() {
    print('$name이(가) 멍멍 짖습니다.');
  }
}

void main() {
  Dog myDog = Dog('바둑이', 3, '진돗개');
  print('이름: ${myDog.name}, 나이: ${myDog.age}, 품종: ${myDog.breed}');
  myDog.makeSound();  // "바둑이이(가) 멍멍 짖습니다."
}

📌 출력 결과

이름: 바둑이, 나이: 3, 품종: 진돗개
바둑이이(가) 멍멍 짖습니다.
✔️ Dog 클래스는 Animal 클래스를 상속받아 makeSound() 메서드를 오버라이딩(재정의) 했습니다.

4. super 키워드 사용법

📌 super 키워드를 사용하면 부모 클래스의 생성자나 메서드를 호출할 수 있습니다.

class Animal {
  String name;
  Animal(this.name);

  void move() {
    print('$name이(가) 움직입니다.');
  }
}

class Bird extends Animal {
  Bird(String name) : super(name);

  @override
  void move() {
    super.move(); // 부모 클래스의 move() 메서드 호출
    print('$name이(가) 날아갑니다.');
  }
}

void main() {
  Bird sparrow = Bird('참새');
  sparrow.move();
}​

📌 출력 결과

참새이(가) 움직입니다.
참새이(가) 날아갑니다.​

✔️ super.move();를 사용하여 부모 클래스의 move()를 호출한 후, 추가적인 동작을 수행했습니다.


5. @override를 활용한 메서드 재정의

📌 부모 클래스의 기능을 그대로 사용하지 않고, 변경하고 싶을 때 @override 키워드를 사용합니다.

class Vehicle {
  void start() {
    print('차량이 출발합니다.');
  }
}

class Car extends Vehicle {
  @override
  void start() {
    print('자동차 시동을 겁니다.');
  }
}

void main() {
  Car myCar = Car();
  myCar.start();  // "자동차 시동을 겁니다."
}​

✔️ 오버라이딩을 사용하면 부모 클래스의 기능을 자식 클래스에서 원하는 대로 변경할 수 있습니다.


6. abstract 클래스 (추상 클래스)

📌 추상 클래스는 인스턴스화할 수 없으며, 자식 클래스가 반드시 구현해야 하는 메서드를 정의할 때 사용됩니다.
추상 클래스는 abstract 키워드를 사용하여 정의합니다.

abstract class Animal {
  void makeSound(); // 구현 없이 선언만 함
}

class Dog extends Animal {
  @override
  void makeSound() {
    print('멍멍!');
  }
}

class Cat extends Animal {
  @override
  void makeSound() {
    print('야옹~');
  }
}

void main() {
  Dog dog = Dog();
  dog.makeSound();  // "멍멍!"

  Cat cat = Cat();
  cat.makeSound();  // "야옹~"
}​

✔️ Animal 클래스는 추상 클래스이므로 makeSound() 메서드를 구현하지 않았습니다.
✔️ Dog, Cat 클래스는 이를 오버라이딩하여 각각 다른 동작을 정의했습니다.


7. 다중 상속이 안 될 때 mixin 활용

📌 Dart에서는 다중 상속을 지원하지 않지만, mixin을 사용하면 여러 클래스의 기능을 조합할 수 있습니다.

mixin Flyable {
  void fly() {
    print('날아오릅니다!');
  }
}

mixin Swimmable {
  void swim() {
    print('헤엄칩니다!');
  }
}

class Duck with Flyable, Swimmable {
  void quack() {
    print('꽥꽥!');
  }
}

void main() {
  Duck duck = Duck();
  duck.fly();   // "날아오릅니다!"
  duck.swim();  // "헤엄칩니다!"
  duck.quack(); // "꽥꽥!"
}​

✔️ Duck 클래스는 Flyable, Swimmable을 mixin을 사용하여 포함시킵니다.
✔️ 이를 통해 다중 상속처럼 여러 기능을 결합할 수 있습니다.


8. 상속을 활용한 실제 예제

📌 은행 시스템 예제 (상속 적용)

class Account {
  String owner;
  double balance;

  Account(this.owner, this.balance);

  void deposit(double amount) {
    balance += amount;
    print('$amount 원 입금됨. 현재 잔액: $balance 원');
  }

  void withdraw(double amount) {
    if (amount > balance) {
      print('잔액 부족!');
    } else {
      balance -= amount;
      print('$amount 원 출금됨. 현재 잔액: $balance 원');
    }
  }
}

class SavingsAccount extends Account {
  double interestRate;

  SavingsAccount(String owner, double balance, this.interestRate) : super(owner, balance);

  void addInterest() {
    double interest = balance * interestRate;
    deposit(interest);
    print('이자 지급: $interest 원');
  }
}

void main() {
  SavingsAccount myAccount = SavingsAccount('홍길동', 10000, 0.05);
  myAccount.deposit(5000);
  myAccount.withdraw(3000);
  myAccount.addInterest();
}​

✔️ Account 클래스를 상속받아 SavingsAccount에서 이자 기능을 추가했습니다.


9. 정리

  • 상속(extends): 부모 클래스의 속성과 메서드를 재사용할 수 있음.
  • super 키워드: 부모 클래스의 생성자 및 메서드를 호출.
  • 메서드 오버라이딩(@override): 부모 메서드를 재정의하여 기능을 변경.
  • 추상 클래스(abstract): 직접 인스턴스화할 수 없으며, 자식 클래스가 구현해야 함.
  • mixin 활용: 다중 상속 대신 여러 기능을 조합.

📌 상속을 활용하면 코드 재사용성을 높이고 객체지향적인 설계를 할 수 있습니다! 🚀

'Programming > Dart' 카테고리의 다른 글

Dart Interface  (0) 2025.03.27
Dart Override  (0) 2025.03.27
Dart 파일 구조  (0) 2025.03.25
Dart Import  (0) 2025.03.25
Dart 소개  (0) 2025.03.25