반응형
추상 클래스와 인터페이스를 알아보자
- 플러터를 시작하기 전 다트(Dart) 언어의 개념에 대해 정리를 해보고자 합니다.
- 다트(Dart) 언어 개념 정리 포스팅 후 플러터(Flutter) 개념 정리로 넘어갈 예정입니다.
- 플러터(Flutter) 개념 정리 후 실습이 시작 된다고 보시면 될 것 같습니다.
소개
- 다트(Dart)는 구글이 개발한 현대적이고 강력한 프로그래밍 언어입니다.
- 특히 Flutter 프레임워크와 함께 사용되어 모바일, 웹, 데스크톱 애플리케이션 개발에 널리 활용되고 있습니다.
- 다트의 주요 특징 중 하나는 강력한 객체지향 프로그래밍(OOP) 지원인데, 이번 포스팅에서는 OOP의 핵심 개념인 추상 클래스와 인터페이스에 대해 자세히 알아보도록 하겠습니다.
추상 클래스(Abstract Class)란?
추상 클래스는 하나 이상의 추상 메서드를 포함하는 클래스를 말합니다. 추상 메서드는 선언만 있고 구현이 없는 메서드입니다. 추상 클래스는 직접 인스턴스화할 수 없으며, 다른 클래스에서 상속받아 구현해야 합니다.
추상 클래스의 특징
abstract
키워드를 사용하여 정의합니다.- 추상 메서드와 일반 메서드를 모두 포함할 수 있습니다.
- 생성자를 가질 수 있습니다.
- 다중 상속은 지원하지 않습니다.
추상 클래스 예제
abstract class Animal {
void makeSound(); // 추상 메서드
void eat() {
print('The animal is eating.'); // 일반 메서드
}
}
class Dog extends Animal {
@override
void makeSound() {
print('The dog barks: Woof! Woof!');
}
}
void main() {
var dog = Dog();
dog.makeSound(); // 출력: The dog barks: Woof! Woof!
dog.eat(); // 출력: The animal is eating.
}
- 이 예제에서
Animal
은 추상 클래스이고,Dog
클래스가 이를 상속받아makeSound()
메서드를 구현하고 있습니다.
인터페이스(Interface)란?
다트는 별도의 interface
키워드를 제공하지 않습니다. 대신, 모든 클래스가 암시적으로 인터페이스 역할을 할 수 있습니다. 인터페이스는 클래스가 구현해야 하는 메서드의 집합을 정의합니다.
인터페이스의 특징
- 별도의 키워드 없이 일반 클래스처럼 정의합니다.
- 모든 메서드가 추상 메서드로 간주됩니다.
implements
키워드를 사용하여 구현합니다.- 다중 구현이 가능합니다.
인터페이스 예제
class Flyable {
void fly() {}
}
class Swimmable {
void swim() {}
}
class Duck implements Flyable, Swimmable {
@override
void fly() {
print('The duck is flying.');
}
@override
void swim() {
print('The duck is swimming.');
}
}
void main() {
var duck = Duck();
duck.fly(); // 출력: The duck is flying.
duck.swim(); // 출력: The duck is swimming.
}
- 이 예제에서
Flyable
과Swimmable
은 인터페이스 역할을 하는 클래스이고,Duck
클래스가 이 두 인터페이스를 구현하고 있습니다.
추상 클래스 vs 인터페이스
추상 클래스와 인터페이스는 비슷해 보이지만 몇 가지 중요한 차이점이 있습니다:
- 상속 vs 구현 : 추상 클래스는
extends
키워드로 상속받고, 인터페이스는implements
키워드로 구현합니다. - 다중 상속/구현 : 다트에서는 하나의 클래스만 상속할 수 있지만, 여러 인터페이스를 구현할 수 있습니다.
- 메서드 구현 : 추상 클래스는 일부 메서드에 대한 기본 구현을 제공할 수 있지만, 인터페이스는 모든 메서드가 추상적입니다.
- 생성자 : 추상 클래스는 생성자를 가질 수 있지만, 인터페이스는 생성자를 가질 수 없습니다.
- 용도 : 추상 클래스는 관련된 클래스들 사이의 코드 재사용과 기본 구현을 제공하는 데 유용하고, 인터페이스는 클래스의 공개 API를 정의하는 데 유용합니다.
추상 클래스와 인터페이스의 활용
1. 코드 재사용성 향상
추상 클래스와 인터페이스를 사용하면 코드의 재사용성을 크게 향상시킬 수 있습니다. 공통된 기능을 추상 클래스에 구현하고, 여러 클래스에서 이를 상속받아 사용할 수 있습니다.
abstract class DatabaseConnector {
void connect();
void disconnect();
void query(String sql) {
connect();
print('Executing query: $sql');
disconnect();
}
}
class MySQLConnector extends DatabaseConnector {
@override
void connect() {
print('Connecting to MySQL database...');
}
@override
void disconnect() {
print('Disconnecting from MySQL database...');
}
}
class PostgreSQLConnector extends DatabaseConnector {
@override
void connect() {
print('Connecting to PostgreSQL database...');
}
@override
void disconnect() {
print('Disconnecting from PostgreSQL database...');
}
}
- 이 예제에서
DatabaseConnector
추상 클래스는 데이터베이스 연결에 관한 공통 로직을 제공하고,MySQLConnector
와PostgreSQLConnector
클래스는 각각의 데이터베이스에 맞는 구체적인 연결 방식을 구현합니다.
2. 다형성 구현
인터페이스를 사용하면 다형성을 쉽게 구현할 수 있습니다. 서로 다른 클래스들이 동일한 인터페이스를 구현함으로써, 이들을 동일한 타입으로 처리할 수 있습니다.
abstract class Shape {
double getArea();
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
@override
double getArea() => 3.14 * radius * radius;
}
class Rectangle implements Shape {
final double width;
final double height;
Rectangle(this.width, this.height);
@override
double getArea() => width * height;
}
void printArea(Shape shape) {
print('The area is: ${shape.getArea()}');
}
void main() {
var circle = Circle(5);
var rectangle = Rectangle(4, 6);
printArea(circle); // 출력: The area is: 78.5
printArea(rectangle); // 출력: The area is: 24.0
}
- 이 예제에서
Circle
과Rectangle
클래스는 모두Shape
인터페이스를 구현하고 있어,printArea
함수에서 동일한 방식으로 처리될 수 있습니다.
결론
- 다트의 추상 클래스와 인터페이스는 객체지향 프로그래밍의 핵심 개념을 구현하는 강력한 도구입니다. 이들을 적절히 활용하면 코드의 재사용성, 확장성, 유지보수성을 크게 향상시킬 수 있습니다. 추상 클래스는 관련된 클래스들 사이의 공통 기능을 구현하고 코드를 재사용하는 데 유용하며, 인터페이스는 클래스의 공개 API를 정의하고 다형성을 구현하는 데 효과적입니다.
- 개발자로서 이 두 개념의 차이점과 각각의 장단점을 이해하고 적절한 상황에서 활용하는 것이 중요합니다. 프로젝트의 요구사항과 설계 방식에 따라 추상 클래스와 인터페이스를 적절히 조합하여 사용하면, 더욱 견고하고 유연한 코드를 작성할 수 있을 것입니다.
- 다트와 Flutter를 사용하여 애플리케이션을 개발할 때, 이러한 객체지향 프로그래밍의 원칙들을 잘 활용한다면 더욱 효율적이고 유지보수가 용이한 코드를 작성할 수 있을 것입니다. 지속적인 학습과 실습을 통해 이러한 개념들을 마스터하고, 실제 프로젝트에 적용해 보시기를 추천 드립니다.
맺음말
- 이번 포스팅에서는 다트의 추상 클래스와 인터페이스에 대해 알아보았습니다.
- 다음 포스팅에서는 다트의 Getter와 Setter에 대해 알아보고자 합니다.
반응형
'다트(Dart) 언어 강좌' 카테고리의 다른 글
예외 처리를 알아보자 (0) | 2024.07.26 |
---|---|
Getter와 Setter 를 알아보자 (0) | 2024.07.26 |
상속과 다형성을 알아보자 (0) | 2024.07.25 |
생성자와 메서드를 알아보자 (0) | 2024.07.25 |
객체 지향 프로그래밍의 핵심을 알아보자 (0) | 2024.07.24 |