본문 바로가기
IT/Flutter

2회. Flutter 실무에 필요한 Dart 중급 문법

by eplus 2026. 6. 27.

1. 중급 Dart가 중요한 이유

Flutter 앱을 만들다 보면 단순한 변수와 함수만으로는 한계가 있습니다.
로그인 사용자 정보, 게시글, 상품, 주문, 센서 데이터, API 응답값 등을 구조적으로 다뤄야 합니다.

이때 필요한 것이 Dart의 객체지향 문법입니다.

중급 단계에서는 다음 내용을 이해해야 합니다.

  • class
  • 생성자
  • named constructor
  • factory constructor
  • getter / setter
  • 상속
  • abstract class
  • interface
  • mixin
  • enum
  • extension
  • Future와 async/await

이 문법들은 Flutter 실무 코드에서 매우 자주 등장합니다.


2. class 기본

Dart는 객체지향 언어입니다.
데이터와 기능을 하나로 묶을 때 class를 사용합니다.

class User {
  String name;
  int age;

  User(this.name, this.age);

  void introduce() {
    print('이름: $name, 나이: $age');
  }
}

void main() {
  User user = User('Kim', 30);
  user.introduce();
}

User 클래스는 name, age라는 데이터를 가지고 있고, introduce()라는 기능을 가지고 있습니다.

Flutter에서는 사용자, 게시글, 주문, 제품, 장비 상태 등을 class로 많이 표현합니다.


3. 생성자

생성자는 객체를 만들 때 실행되는 특별한 함수입니다.

class Product {
  String name;
  int price;

  Product(this.name, this.price);
}

사용은 다음과 같습니다.

Product p = Product('노트북', 1200000);

Dart에서는 생성자를 간결하게 작성할 수 있습니다.

class Product {
  final String name;
  final int price;

  const Product({
    required this.name,
    required this.price,
  });
}

실무에서는 위와 같은 named parameter 생성자를 많이 사용합니다.

final product = Product(
  name: '노트북',
  price: 1200000,
);

이 방식은 값의 의미가 명확해서 유지보수에 좋습니다.


4. required

Dart에서 named parameter는 기본적으로 선택값입니다.
반드시 입력해야 하는 값에는 required를 붙입니다.

class Member {
  final String id;
  final String name;

  Member({
    required this.id,
    required this.name,
  });
}

사용할 때 id, name을 넣지 않으면 오류가 발생합니다.

final member = Member(
  id: 'user01',
  name: '홍길동',
);

Flutter 위젯 생성자에서도 required를 자주 볼 수 있습니다.


5. fromJson과 toJson

앱 개발에서는 서버와 데이터를 주고받는 일이 많습니다.
서버 API의 JSON 데이터를 Dart 객체로 바꾸기 위해 fromJson()을 자주 사용합니다.

class User {
  final String id;
  final String name;
  final int age;

  User({
    required this.id,
    required this.name,
    required this.age,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['name'],
      age: json['age'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'age': age,
    };
  }
}

사용 예시는 다음과 같습니다.

final json = {
  'id': 'kim',
  'name': '김철수',
  'age': 35,
};

final user = User.fromJson(json);
print(user.name);

final sendData = user.toJson();
print(sendData);

Flutter 앱에서 API 연동을 한다면 이 구조는 반드시 익혀야 합니다.


6. getter와 setter

값을 직접 접근하지 않고 계산하거나 제어하고 싶을 때 getter와 setter를 사용합니다.

class Rectangle {
  double width;
  double height;

  Rectangle(this.width, this.height);

  double get area => width * height;
}

사용은 다음과 같습니다.

final rect = Rectangle(10, 20);
print(rect.area);

area는 변수처럼 사용하지만 실제로는 계산된 값입니다.


7. 상속

상속은 기존 클래스의 기능을 물려받는 문법입니다.

class Animal {
  void move() {
    print('움직입니다.');
  }
}

class Dog extends Animal {
  void bark() {
    print('멍멍');
  }
}

void main() {
  final dog = Dog();
  dog.move();
  dog.bark();
}

DogAnimal의 기능을 사용할 수 있습니다.

다만 실무에서는 무리한 상속보다 조합, interface, mixin을 적절히 사용하는 것이 좋습니다.


8. override

부모 클래스의 기능을 자식 클래스에서 다시 정의할 수 있습니다.

class Animal {
  void sound() {
    print('소리를 냅니다.');
  }
}

class Cat extends Animal {
  @override
  void sound() {
    print('야옹');
  }
}

@override는 부모의 메서드를 재정의했다는 의미입니다.


9. abstract class

추상 클래스는 직접 객체를 만들 수 없고, 공통 규칙을 정의할 때 사용합니다.

abstract class Repository {
  void save();
  void delete();
}

class UserRepository implements Repository {
  @override
  void save() {
    print('사용자 저장');
  }

  @override
  void delete() {
    print('사용자 삭제');
  }
}

Flutter 실무에서는 Repository, Service, Provider, Controller 구조를 만들 때 추상 클래스를 활용할 수 있습니다.


10. mixin

mixin은 여러 클래스에서 공통 기능을 재사용할 때 사용합니다.

mixin Logger {
  void log(String message) {
    print('[LOG] $message');
  }
}

class ApiService with Logger {
  void fetchData() {
    log('데이터 조회 시작');
  }
}

상속은 하나의 클래스만 받을 수 있지만, mixin은 여러 기능을 조합하는 데 유용합니다.


11. enum

정해진 값 중 하나만 선택해야 할 때 enum을 사용합니다.

enum OrderStatus {
  ready,
  processing,
  completed,
  canceled,
}

사용 예시는 다음과 같습니다.

OrderStatus status = OrderStatus.processing;

if (status == OrderStatus.processing) {
  print('처리 중입니다.');
}

문자열로 상태값을 직접 비교하는 것보다 enum을 사용하면 오타를 줄이고 코드 안정성을 높일 수 있습니다.


12. extension

기존 타입에 새로운 기능을 추가할 때 extension을 사용합니다.

extension StringExtension on String {
  bool get isEmail {
    return contains('@');
  }
}

void main() {
  String email = 'test@test.com';
  print(email.isEmail);
}

Flutter 실무에서는 날짜 포맷, 문자열 검증, 숫자 포맷 등에 extension을 자주 활용할 수 있습니다.

예를 들면 금액 표시를 다음처럼 만들 수 있습니다.

extension PriceFormat on int {
  String get won {
    return '$this원';
  }
}

void main() {
  print(12000.won);
}

13. Future

Dart에서 비동기 결과를 표현할 때 Future를 사용합니다.

서버 API 호출, 파일 읽기, DB 조회, 위치 정보 조회 등은 즉시 결과가 나오지 않습니다.
이런 작업을 처리할 때 Future가 필요합니다.

Future<String> fetchData() {
  return Future.delayed(
    Duration(seconds: 2),
    () => '데이터 조회 완료',
  );
}

14. async와 await

asyncawait를 사용하면 비동기 코드를 동기 코드처럼 읽기 쉽게 작성할 수 있습니다.

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return '데이터 조회 완료';
}

void main() async {
  final result = await fetchData();
  print(result);
}

Flutter에서 API를 호출할 때 가장 많이 사용하는 형태입니다.

Future<void> loadUser() async {
  final user = await userRepository.getUser();
  print(user.name);
}

15. try-catch

비동기 작업에서는 오류 처리가 중요합니다.

Future<void> loadData() async {
  try {
    final result = await fetchData();
    print(result);
  } catch (e) {
    print('오류 발생: $e');
  }
}

API 호출, DB 처리, 파일 처리, 권한 요청 등은 항상 실패할 수 있습니다.
따라서 실무 코드에서는 try-catch를 습관적으로 사용하는 것이 좋습니다.


16. 중급 단계에서 꼭 기억할 것

Dart 중급 문법의 핵심은 구조화입니다.

  • class는 데이터를 구조적으로 표현한다.
  • 생성자는 객체를 안전하게 만든다.
  • fromJson()toJson()은 API 연동의 기본이다.
  • 상속은 공통 기능을 재사용할 때 사용한다.
  • abstract class는 규칙을 정의한다.
  • mixin은 공통 기능을 조합한다.
  • enum은 상태값을 안전하게 관리한다.
  • extension은 기존 타입을 확장한다.
  • Future, async, await는 비동기 처리의 핵심이다.
  • try-catch는 앱 안정성을 높인다.

마무리

Dart 중급 문법을 이해하면 Flutter 코드가 훨씬 명확하게 보입니다.
단순히 화면을 만드는 수준을 넘어, 데이터를 어떻게 설계하고, 서버와 어떻게 통신하고, 오류를 어떻게 처리할지 판단할 수 있게 됩니다.

다음 회차에서는 Dart 고급 문법을 다루겠습니다.
Record, Pattern Matching, Stream, Isolate, Generic, sealed class, 코드 구조화 등 실무 품질을 높이는 내용을 정리합니다.

반응형