Flutter/Dart

[DART] 클래스와 인스턴스

연화 2025. 1. 3. 20:30

프로그래밍에서 클래스인스턴스는 객체 지향 프로그래밍(OOP)의 가장 기본적인 개념입니다.
이번 포스팅에서는 클래스와 인스턴스의 정의, 객체 지향 프로그래밍의 개념, 그리고 Dart에서 이를 활용하는 방법에 대해 알아보겠습니다.

 


객체 지향 프로그래밍(OOP)이란?

객체와 객체간에 관계를 형성하고, 그 상호작용을 통해
애플리케이션을 설계, 구현하는 프로그래밍 패러다임 중 하나 입니다.

OOP의 주요 목적은 복잡한 문제를 더 작은 객체로 나누어 해결하는 데 있습니다.
각각의 객체는 자신의 역할에 충실하며, 서로 협력해 문제를 해결합니다.

 

더보기

OOP의 4가지 주요 특징

  • 캡슐화: 데이터를 숨기고, 필요한 메서드만 외부에 제공.
  • 상속: 기존 클래스를 기반으로 새로운 클래스를 정의.
  • 다형성: 동일한 메서드 이름이 다양한 동작을 수행.
  • 추상화: 복잡한 시스템을 단순화하여 핵심적인 부분만 보여줌.

 

 

여기서 클래스(Class)란?

클래스는 객체(인스턴스)를 정의하기 위한 설계도

 

설계도만으로는 아무것도 하지 않지만, 이 설계도를 기반으로 실제 객체를 생성하면 프로그램에서 사용할 수 있습니다.
클래스는 객체가 가질 속성(상태)행위(메서드)를 정의합니다.

 

그렇다면 객체(object)란?

클래스(설계도)를 통해서 프로그램에서 실제로 생성되는 인스턴스

클래스는 설계도지만, 메모리에 올라가면 실제 동작하는 객체가 됩니다.
객체는 보통 속성(상태), 행위(메서드)를 가질 수 있습니다.

 

간단하게 객체 지향 프로그래밍이 무엇인지 살펴보았으니, OOP 기반으로 설계된 Dart 언어에서 이를 활용하는 방법을 알아보겠습니다.
시나리오 코드를 작성하여 단계별로 차근차근 알아가보아요!

 

시나리오 코드 1 - 클래스 만들어 보기
class Dog {
  String name = '토토';
  int age = 5;
  String color = '블랙';
  int thirsty = 100;
}

여기서 Dog 클래스는 강아지를 나타내는 설계도입니다.
강아지는 이름, 나이, 색상, 갈증 지수라는 속성을 가지고 있습니다.

만들어진 Dog 클래스를 통해 객체를 생성하려면 어떻게 해야 할까요?

void main() {

  Dog d1 = Dog(); // Dart에서는 new 키워드를 대부분 생략
  
  print('강아지 이름 ${d1.name}');
  print('강아지 나이 ${d1.age}');
  print('강아지 색상 ${d1.color}');
  print('강아지 현재 갈증 지수 ${d1.thirsty}');

  d1.thirsty = 50;
  print('강아지 현재 갈증 지수 ${d1.thirsty}');
} // end of main

클래스를 기반으로 실제 객체를 생성하고, 이를 통해 속성에 접근하거나 메서드를 호출할 수 있습니다.

 

시나리오 코드 2 - 메서드 만들어 보기
void main() {
  Dog d1 = Dog(); // 다트에서는 new라는 키워드를 대부분 생략

  print('강아지 이름 : ${d1.name}');
  print('강아지 나이 : ${d1.age}');
  print('강아지 색상 : ${d1.color}');
  print('강아지 현재 갈증지수 : ${d1.thirsty}');

  // d1.thirsty = 50;
  d1.drinkWater(5);
  print('강아지 현재 갈증지수 : ${d1.thirsty}');
} 

class Dog {
  // 변수에 선언과 동시에 초기화(값을 넣다)
  String name = '토토';
  int age = 5;
  String color = 'black';
  int thirsty = 100;

  // 물을 마실 때마다 갈증지수가 10씩 내려가는 메서드
  void drinkWater(int count) {
    thirsty = thirsty - 10 * count;
  }
}

실행결과

시나리오 코드 3 - 협력하기(상호작용)
void main() {
  Dog d1 = Dog();
  Water wt = Water();

  print('강아지 현재 갈증지수 : ${d1.thirsty}');
  print('현재 물의 양 : ${wt.liter}');

  d1.drinkWater(wt);
  print('강아지 현재 갈증지수 : ${d1.thirsty}');
  print('현재 남은 물의 양 : ${wt.liter}');
}

class Dog {
  String name = '토토';
  int age = 5;
  String color = 'black';
  int thirsty = 100;

  // 물을 마실 때마다 갈증지수가 10씩 내려가는 메서드
  void drinkWater(Water wt) {
    thirsty = thirsty - 10;
    wt.drink();
  }
}

class Water {
  double liter = 2.0; //물 2리터

  void drink() {
    liter -= 0.1;
  }
}

실행 결과

 

시나리오 코드 4 - 생성자 만들기와 생성자 오버로딩은 없다.
// 코드의 진입점
void main() {
  // 생성자
} // end of main

// dart 라는 언어는 기본적으로 null 값을 허용 하지 않는다.
class Dog {
  String name;
  int age;
  String color;
  int thirsty;

  // Dog(this.name, this.age, this.color, this.thirsty) {}
  Dog(this.name, this.age, this.color, this.thirsty); // 생성자 구현 부분 생략 가능
  // Dog(this.name, this.age); 이거 안됨 --> dart 에서는 생성자 오버로딩이 없다.
}

class Water {
  double liter = 2.0; // 물 2리터

  void drink() {
    // liter = liter - 0.1;
    liter -= 0.1;
  }
}

 

시나리오 코드 5 - 선택적 명명 매개변수
  • 선택적 위치 매개변수 (Optional Positional Paramters)
  • 선택적 명명 매개변수 (Optional Named Paramters)
// 코드의 진입점
void main() {
  // 생성자
  Dog(name: '토토', age: 5);

// dart 라는 언어는 기본적으로 null 값을 허용 하지 않는다.
class Dog {
  String name;
  int age;
  // String 옵셔널 타입은 null 허용 시키는 타입이다.
  String? color;
  int? thirsty;

  // {} 붙이면 선택적 명명 매개 변수
  Dog(
      {required this.name,
      required this.age,
      this.color = '블랙',
      this.thirsty = 100});
}

class Water {
  double liter = 2.0; // 물 2리터

  void drink() {
    // liter = liter - 0.1;
    liter -= 0.1;
  }
}

 

시나리오 코드 6 - 캐드케이스 연산자 (cascade)
  • 캐스케이스 연산자 (cascade)
    .. 연산자를 사용하면 동일 객체에서 여러 메서드나 속성을 연속적으로 호출할 수 있는 유용한 연산자
class Person {
  String? name;
  int money = 0;

  void setName(String newName) {
    this.name = newName;
  }

  void addMoney(int amount) {
    this.money += amount;
  }
}

void main() {
  var p1 = Person()
    ..setName('홍길동')
    ..addMoney(5000)
    ..money += 2000;
  print(p1.name);
  print(p1.money);
} // end of main

 

 

 

이번 포스팅에서는 Dart의 객체 지향 프로그래밍(OOP) 개념을 중심으로
클래스와 인스턴스, 그리고 이를 활용한 다양한 시나리오 코드를 살펴보았습니다.
Dart는 단순하면서도 강력한 문법을 제공하여 OOP의 주요 개념인 캡슐화, 상속, 다형성, 추상화를 효과적으로 구현할 수 있습니다.

 

 

 

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

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

[DART] 상속(Inheritance)이란 무엇인가요?  (0) 2025.01.06
[DART] Sound Null Safety in dart  (0) 2025.01.06
[DART] 익명함수와 화살표함수  (1) 2025.01.03
[DART] 기본 연산자  (0) 2025.01.03
[DART] Dart 기본 문법 익히기  (0) 2025.01.03