Flutter/Dart 언어

[Dart] dart의 추상 클래스

공돌이 출신 개발자 2025. 1. 8. 19:17
728x90
Dart의 추상 클래스

추상 클래스란?

  • 추상적인 클래스이기 때문에 **인스턴스화(객체 생성)**할 수 없습니다.
  • 완전한 구현을 제공하지 않으며, 이를 상속받는 클래스가 구체적인 동작을 구현하도록 강제합니다.

특징

  1. 공통된 속성과 메서드 정의
    • 여러 클래스에서 공유할 속성과 메서드를 정의합니다.
  2. 구현 강제
    • 추상 메서드를 선언하여, 상속받은 클래스에서 반드시 구현하도록 강제합니다.
  3. 일반화된 개념 표현
    • 구체적인 동작이 아니라 일반적인 동작을 정의합니다
✔ 우리 회사는 유아용 동물 소리 프로그램을 만듭니다. 그리고 팀장님께서 물고기 소리 나는 프로그램을
만들어 달라 요청을 했다면 어떻게 될까요?
(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 구현을 실행 시점에 동적으로 호출합니다. 이를 통해 유연하고 확장 가능한 설계를 구현할 수 있습니다.

// Animal 추상클래스를 구현해서 만들어 줘 라고 부탁 했어야 한다.
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 start1(Cat c) {
  c.performAction();
}

void start2(Dog d) {
  d.performAction();
}

void start3(Fish f) {
  f.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] 클래스와 인스턴스

클래스와 객체란?클래스(Class)클래스는 객체를 정의하는 설계도입니다.클래스 = 설계도예: 자동차의 설계도객체(Object)객체는 클래스를 기반으로 생성된 실제 인스턴스를 의미합니다.객체 = 설계

seohong.tistory.com