Flutter/Dart

[DART] dart의 추상 클래스

연화 2025. 1. 7. 20:22

 

객체지향 프로그래밍(OOP)에서 추상 클래스는 특정 동작이나 속성을 강제하기 위한 강력한 도구입니다.
Dart에서도 추상 클래스는 상속을 통해 일반화된 동작을 구체적인 구현으로 확장할 수 있는 기회를 제공합니다.
이번 포스팅에서는 Dart의 추상 클래스에 대해 알아보고,
왜 추상 클래스가 필요한지,
그리고 실전 코드에서 어떻게 활용되는지를 살펴보겠습니다.

 

1. 추상 클래스란?

추상 클래스(Abstract Class)는 완전한 구현을 제공하지 않는 클래스입니다.
특정 동작을 서브 클래스가 반드시 구현하도록 강제할 수 있습니다.

  • 인스턴스화 불가: 추상 클래스는 직접 객체를 생성할 수 없습니다.
  • 추상 메서드: 메서드 본체가 없는, 반드시 구현해야 하는 메서드를 포함할 수 있습니다.
  • 상속 필수: 추상 클래스는 다른 클래스가 이를 상속하고 구체적인 동작을 정의하도록 설계됩니다.

 

2. 추상 클래스 없이 설계할 때 발생하는 문제

아래는 유아용 동물 소리 프로그램의 예시입니다.

✔ 우리 회사는 유아용 동물 소리 프로그램을 만듭니다. 그리고 팀장님께서 물고기 소리 나는 프로그램을 만들어 달라 요청을 했다면 어떻게 될까요?
(Dog 클래스와 Cat 클래스는 이미 설계되어 있음)
// 팀장이 물고기 소리 나는 프로그램을 만들어 달라 요청을 했다면?
class Dog {
  void performAction() {
    print('멍멍 배고파');
  }
}

class Cat {
  void performAction() {
    print('야옹 배고파');
  }
}

//신입이 작성했다고 가정
class Fish {
  void hungry() {
    print('뻐끔뻐끔 배고파');
  }
}

void main() {
  Dog d = Dog();
  Cat c = Cat();
  Fish f = Fish();
  f.hungry();
  // f.performAction(); 동적인 코드로 돌렸다면 오류 발생(Fish 클래스에는 performAction이 없음)
}

3. 추상 클래스를 활용한 해결

💡 이때 추상 클래스를 활용하면 손쉽게 해결할 수 있습니다.
Animal 추상 클래스를 만들어 모든 동물이 공통적으로 가져야 할 동작(performAction)을 정의합니다.
abstract class Animal {
  void performAction();
}
class Dog implements Animal {
  @override
  void performAction() {
    print('멍멍 배고파');
  }
}

class Cat implements Animal {
  @override
  void performAction() {
    print('야옹 배고파');
  }
}

class Fish implements Animal {
  @override
  void performAction() {
    print('뻐끔뻐끔 배고파');
  }
}

동적 바인딩을 활용한 설계

이제 동적 바인딩을 통해 다양한 동물 객체를 동일한 방식으로 처리할 수 있습니다.

  • 모든 동물 클래스는 performAction을 반드시 구현해야 하므로 일관성을 유지
  • start 함수는 동적 바인딩을 통해 다양한 동물 객체를 처리
void start(Animal a) {
  a.performAction(); // 동적으로 호출
}

void main() {
  start(Dog());
  start(Cat());
  start(Fish());
}

4. 동적 바인딩이란?

동적 바인딩(Dynamic Binding)은 프로그램 실행 중에 호출할 메서드를 결정하는 방식입니다.
위 코드에서 start 함수는 Dog, Cat, Fish 객체의 구체적인 performAction 구현을 실행 시점에 동적으로 호출합니다. 이를 통해 유연하고 확장 가능한 설계를 구현할 수 있습니다.

abstract class Animal {
  void performAction();
}

// 추상 클래스를 구현할 때 implements 를 사용
class Dog implements Animal {
  @override
  void performAction() {
    print('멍멍 배고파');
  }
}

class Cat implements Animal {
  @override
  void performAction() {
    print('야옹 배고파');
  }
}

class Fish implements Animal {
  @override
  void performAction() {
    print('뻐끔뻐끔 배고파');
  }
}

// 한 단계 더 나아가 보자~ 실력 쌓기
// 동적 바인딩이란 뭘까?
void start(Animal a) {
  // performAction() 메서드가 동작하게 만들고 싶다.
  // 단, 강아지든 고양이든 물고기든 동적으로 들어오더라도 performAction이 호출되도록 설계
  a.performAction();
}

void main() {
  start(Dog());
  start(Cat());
  start(Fish());
}

 

4 - 2. 추상 클래스 사용 연습

추상 클래스와 동적 바인딩을 활용한 다형성 구현하기

Shape라는 추상 클래스를 정의하고, 이를 상속받은 Circle과 Rectangle 클래스가 있습니다. calculateArea 함수를 통해 동적 바인딩을 활용하여 다양한 도형의 면적을 계산할 수 있도록 구현하세요
//추상 클래스
abstract class Shape {
  // 메서드의 바디(구현부)가 없다면 추상 메서드
  double getArea();
}

// 문제가 뭐지? 면적을 구하는 일을 해결해야 한다.
class Circle implements Shape {
  final double radius;

  // 생성자는 가능한 축약형으로 만들자 - 우리들의 규칙
  Circle(this.radius);

  // 면적을 구하는 행위
  @override
  double getArea() {
    return 3.14 * radius * radius;
  }
}

class Rectangle implements Shape {
  final double width;
  final double height;

  Rectangle(this.width, this.height);

  // 면적을 구하는 행위를 해야 한다
  @override
  double getArea() {
    return width * height;
  }
}

// 동적 바인딩을 활용한 함수를 설계해 보자
// 전역 함수 설계
void calculateArea(Shape s) {
  // 전달된 도형의 면적을 출력하시오.
  print(s.getArea());
}

void main() {
  Shape myCir = Circle(5.3);
  Shape myRec = Rectangle(4.0, 3.5);

  calculateArea(myCir);
  calculateArea(myRec);
}

 

Dart에서 추상 클래스를 사용해야 할 때
    공통된 속성과 메서드가 필요한 경우
    반드시 구현해야 할 동작을 서브 클래스에 강제하려는 경우

 

 

추상 클래스는 객체 지향 프로그래밍(OOP)에서 설계의 강력한 도구로,
클래스 간의 일관성과 재사용성을 확보하는 데 큰 도움을 줍니다.
Dart에서 추상 클래스는 공통된 동작을 강제하거나, 동적 바인딩을 활용한 유연한 설계를 가능하게 합니다.
추상 클래스를 올바르게 활용하면 코드의 가독성과 유지보수성이 향상될 뿐만 아니라,
협업 과정에서도 명확한 설계를 제공할 수 있습니다.

 

❓ dart에서 클래스를 설계하는 방법이 궁금하다면?

 

[DART] 클래스와 인스턴스

프로그래밍에서 클래스와 인스턴스는 객체 지향 프로그래밍(OOP)의 가장 기본적인 개념입니다.이번 포스팅에서는 클래스와 인스턴스의 정의, 객체 지향 프로그래밍의 개념, 그리고 Dart에서 이를

dev-yeonwha.tistory.com

 

아래의 문헌을 참고하여 작성된 포스팅입니다.
최주호, 김근호, 이지원(공저) 『만들면서 배우는 플러터 앱 프로그래밍』, 앤써북, 2023.