Dart의 객체지향 프로그래밍(OOP) 핵심 개념을 전체적으로 정리해드리겠습니다. 개념 설명 → 실습 예제 2개 + 해설 방식으로 구성하였습니다. 오늘은 전체 구조를 보여드리고, 각 항목마다 예시를 순차적으로 확장할 수 있습니다.
🚀 Dart 객체지향 프로그래밍 (OOP) 완전 정복
세상의 모든 것(사람, 동물, 자동차 등)을 코드로 표현하는 방법!
Dart에서 OOP를 잘 이해하면 코드가 더 똑똑하고 재사용 가능하게 됩니다.
✅ 1. 클래스(Class)와 객체(Object)
📘 개념 설명
-
클래스: 설계도 (예: 강아지라는 개념)
-
객체: 설계도로 만든 실제 사물 (예: 우리 집 강아지 ‘코코’)
🏆 실습 예제 1: 간단한 클래스 만들기
class Dog {
String name = '코코';
void bark() {
print('$name가 멍멍 짖어요!');
}
}
void main() {
Dog myDog = Dog();
myDog.bark();
}
🏆 실습 예제 2: 다른 동물 클래스 만들어보기
학생이 스스로 고양이 클래스를 만들어보는 과제 제공!
✅ 2. 생성자(Constructor) & 초기화 리스트
📘 개념 설명
-
생성자는 객체를 만들 때 자동으로 호출되는 함수
-
초기화 리스트(:)로 변수 값을 빠르게 설정 가능
🏆 실습 예제 1: 생성자 사용하기
class Student {
String name;
int age;
Student(this.name, this.age);
}
void main() {
Student s1 = Student('지훈', 13);
print('${s1.name} 학생은 ${s1.age}살입니다.');
}
🏆 실습 예제 2: 초기화 리스트 활용
class Circle {
final double radius;
final double area;
Circle(this.radius) : area = 3.14 * radius * radius;
}
void main() {
Circle c = Circle(5);
print('원의 넓이: ${c.area}');
}
✅ 3. this 키워드
📘 개념 설명
-
this는 클래스 자신을 가리켜요.
-
매개변수 이름과 변수 이름이 같을 때 구분할 때 사용.
🏆 실습 예제 1:
class Car {
String brand;
Car(String brand) {
this.brand = brand;
}
}
✅ 4. 인스턴스 변수와 메서드
📘 개념 설명
인스턴스 변수는 객체마다 각각 다르게 가질 수 있는 값입니다.
인스턴스 메서드는 각 객체가 가진 값에 따라 다른 동작을 합니다.
🏆 실습 예제 1: 인스턴스 변수 사용하기
class Student {
String name = '';
int age = 0;
void introduce() {
print('안녕하세요, 저는 $name이고, $age살입니다.');
}
}
void main() {
Student s1 = Student();
s1.name = '지훈';
s1.age = 13;
s1.introduce();
Student s2 = Student();
s2.name = '민지';
s2.age = 12;
s2.introduce();
}
✅ 출력:
안녕하세요, 저는 지훈이고, 13살입니다.
안녕하세요, 저는 민지고, 12살입니다.
🏆 실습 예제 2: 인스턴스 메서드로 사칙연산
class Calculator {
int x = 0;
int y = 0;
int add() {
return x + y;
}
}
void main() {
Calculator c = Calculator();
c.x = 7;
c.y = 5;
print('결과: ${c.add()}');
}
✅ 출력:
결과: 12
✅ 5. 정적 변수/메서드 (static)
📘 개념 설명
static 키워드가 붙으면, 클래스 전체에서 공유하는 변수 또는 함수가 됩니다.
객체를 만들지 않아도 사용 가능!
🏆 실습 예제 1: 클래스 전체에서 같은 값을 공유
class Counter {
static int total = 0;
void increment() {
total++;
}
}
void main() {
Counter c1 = Counter();
Counter c2 = Counter();
c1.increment();
c2.increment();
print('총 클릭 수: ${Counter.total}');
}
✅ 출력:
총 클릭 수: 2
🏆 실습 예제 2: static 메서드로 유틸리티 만들기
class MathTool {
static int square(int x) {
return x * x;
}
}
void main() {
print(MathTool.square(5)); // 출력: 25
}
✅ 6. 상속 (extends)
📘 개념 설명
부모 클래스의 속성과 기능을 자식 클래스가 물려받아 사용하거나 확장할 수 있어요.
🏆 실습 예제 1: 상속으로 기능 확장
class Animal {
void sound() {
print('동물이 소리를 냅니다.');
}
}
class Dog extends Animal {
void bark() {
print('멍멍!');
}
}
void main() {
Dog d = Dog();
d.sound();
d.bark();
}
✅ 출력:
동물이 소리를 냅니다.
멍멍!
🏆 실습 예제 2: 상속 받은 메서드 오버라이딩
class Animal {
void sound() {
print('동물이 소리 냄');
}
}
class Cat extends Animal {
@override
void sound() {
print('야옹~');
}
}
void main() {
Animal a = Cat();
a.sound();
}
✅ 출력:
야옹~
✅ 7. 추상 클래스 (abstract)
📘 개념 설명
추상 클래스는 실제 객체로 만들 수는 없지만,
자식 클래스가 따라야 할 설계도 역할을 해요.
🏆 실습 예제 1: 추상 클래스 만들기
abstract class Shape {
double getArea();
}
class Rectangle extends Shape {
double width;
double height;
Rectangle(this.width, this.height);
@override
double getArea() => width * height;
}
void main() {
Rectangle r = Rectangle(5, 4);
print('넓이: ${r.getArea()}');
}
🏆 실습 예제 2: 여러 도형의 넓이 계산하기
abstract class Shape {
double getArea();
}
class Circle extends Shape {
double radius;
Circle(this.radius);
@override
double getArea() => 3.14 * radius * radius;
}
void main() {
Shape s = Circle(3);
print('넓이: ${s.getArea()}');
}
✅ 8. 인터페이스와 다형성
📘 개념 설명
여러 클래스가 같은 방식으로 동작할 수 있게 하는 약속이에요.
Dart는 클래스 자체가 인터페이스처럼 사용됨!
🏆 실습 예제 1: 인터페이스처럼 클래스 구현
class Flyable {
void fly() => print('날아갑니다!');
}
class Bird implements Flyable {
@override
void fly() {
print('새가 하늘을 납니다!');
}
}
void main() {
Flyable f = Bird();
f.fly();
}
🏆 실습 예제 2: 여러 객체를 한 타입으로 다루기
abstract class Speaker {
void speak();
}
class Human implements Speaker {
@override
void speak() => print('사람이 말해요!');
}
class Robot implements Speaker {
@override
void speak() => print('로봇이 말합니다.');
}
void main() {
List<Speaker> speakers = [Human(), Robot()];
for (var s in speakers) {
s.speak();
}
}
✅ 9. 믹스인 (with)
📘 개념 설명
클래스 여러 개의 기능을 조합해서 하나의 클래스로 만들 수 있어요.
코드 복사 없이 기능을 쉽게 합칠 수 있는 방법이에요.
🏆 실습 예제 1: 믹스인 사용하기
mixin Walk {
void walk() => print('걷는 중...');
}
mixin Swim {
void swim() => print('수영 중...');
}
class Human with Walk, Swim {}
void main() {
Human h = Human();
h.walk();
h.swim();
}
🏆 실습 예제 2: 믹스인으로 기능 재사용
mixin Fly {
void fly() => print('날아가는 중...');
}
class SuperMan with Fly {}
void main() {
SuperMan s = SuperMan();
s.fly();
}
✅ 10. factory 생성자
📘 개념 설명
factory 키워드는 특별한 방식으로 객체를 생성할 때 사용해요.
매번 새로운 객체를 만들지 않고, 조건에 따라 기존 객체를 재사용할 수 있어요.
🏆 실습 예제 1: 조건에 따라 다른 객체 반환
class User {
final String id;
static final Map<String, User> _cache = {};
factory User(String id) {
if (_cache.containsKey(id)) {
return _cache[id]!;
} else {
final user = User._internal(id);
_cache[id] = user;
return user;
}
}
User._internal(this.id);
}
void main() {
var u1 = User('abc');
var u2 = User('abc');
print(u1 == u2); // true
}
🏆 실습 예제 2: 문자열에 따라 객체 다르게 만들기
class Animal {
String type;
factory Animal.create(String name) {
if (name == 'dog') {
return Dog();
} else if (name == 'cat') {
return Cat();
} else {
throw '알 수 없는 동물입니다';
}
}
Animal(this.type);
}
class Dog extends Animal {
Dog() : super('강아지');
}
class Cat extends Animal {
Cat() : super('고양이');
}
void main() {
Animal a = Animal.create('dog');
print(a.type); // 강아지
}
📘 마무리 요약
기능 |
핵심 설명 |
---|---|
인스턴스 |
객체 고유의 변수와 함수 |
static |
클래스 전체가 공유하는 변수와 함수 |
상속 |
부모 클래스의 기능을 물려받음 |
추상 클래스 |
설계만 있고 직접 객체 생성은 안 됨 |
인터페이스 |
같은 동작 방식의 약속 |
믹스인 |
클래스 기능 조합 |
factory |
조건에 따라 객체 생성, 재사용 가능 |
📚 마무리: Dart OOP 핵심 요약
개념 |
설명 |
---|---|
클래스 & 객체 |
설계도와 실제 물건 |
생성자 |
객체를 만들 때 자동 호출되는 함수 |
this |
클래스 자기 자신 |
static |
모두가 공유하는 변수/함수 |
상속 |
부모 클래스의 기능 물려받기 |
추상 클래스 |
설계만 존재, 직접 생성 불가 |
인터페이스 |
동작 방식을 통일 |
믹스인 |
여러 클래스 기능 합치기 |
factory 생성자 |
특별한 방식으로 객체 생성 |
댓글 쓰기