ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Dart 5#. 클래스와 생성자
    프론트/Dart 2025. 10. 6. 20:01

    1. 클래스의 기본 구조

    Dart에서 **클래스(class)**는 객체의 설계도 역할을 하며, **속성(필드)**과 **동작(메서드)**을 함께 정의한다.
    클래스는 객체지향 프로그래밍(OOP)의 핵심 개념이며, 인스턴스를 통해 실제 데이터를 다룰 수 있다.

    class Player {
      final String name; // 변경 불가한 속성
      int xp;
    
      // 기본 생성자
      Player(this.name, this.xp);
    
      void sayHello() {
        print("Hi my name is $name");
      }
    }
    
    void main() {
      var player = Player('jeongwon', 1500);
      player.sayHello(); // Hi my name is jeongwon
    }
    

    👉 핵심: 클래스는 데이터를 묶고, 생성자를 통해 초기화한다.
    final은 한 번 설정된 값을 변경할 수 없다.


    2. 생성자 (Constructor)

    생성자는 인스턴스가 만들어질 때 필드를 초기화하는 특별한 메서드이다.
    Dart에서는 기본 생성자, 이름 있는 생성자, 초기화 리스트(initializer list), factory 생성자 등을 지원한다.

    (1) 기본 생성자

    class Player {
      final String name;
      int xp;
    
      Player(this.name, this.xp);
    }
    

    👉 클래스 이름과 동일하며, (this.name, this.xp)는 전달받은 인자를 바로 필드에 할당한다.


    (2) 이름 있는 생성자 (Named Constructor)

    클래스 안에 여러 생성자를 둘 수 있다.
    ClassName.이름() 형태로 선언하며, 특정 상황에 맞는 초기화 방식을 제공한다.

    class Player {
      final String name;
      int xp;
    
      Player(this.name, this.xp);
    
      // 이름 있는 생성자
      Player.beginner(String name) : this(name, 0);
      Player.pro(String name) : this(name, 5000);
    }
    
    void main() {
      var p1 = Player.beginner("jeongwon");
      var p2 = Player.pro("kim");
    }
    

    👉 핵심: 클래스 내부에서 다양한 초기화 패턴을 가독성 좋게 표현할 수 있다.


    (3) 이름 있는 매개변수 (Named Parameters)

    생성자나 함수의 인자를 {}로 감싸면, 호출 시 인자명을 명시할 수 있어 코드 가독성이 향상된다.

    class Player {
      final String name;
      int xp;
    
      Player({required this.name, required this.xp});
    }
    
    void main() {
      var player = Player(name: "jeongwon", xp: 1200);
    }
    

    👉 핵심: {} + required 조합으로 필수 매개변수를 안전하게 전달 가능.


    (4) 초기화 리스트 (Initializer List)

    생성자 본문이 실행되기 전에 필드를 초기화할 수 있다.
    : 뒤에 초기화 식을 작성한다.

    class Player {
      final String name;
      final int xp;
    
      Player(String n, int x) : name = n, xp = x;
    }
    

    👉 핵심: : 이후 구문은 super() 호출 전에 실행된다. 주로 final 필드 초기화 시 사용.


    (5) factory 생성자

    일반 생성자와 달리 새 인스턴스를 반드시 반환하지 않아도 되며,
    캐싱, 싱글턴, 다른 타입 반환 등 유연한 생성 로직을 구현할 수 있다.

    class Player {
      final String name;
      static final Map<String, Player> _cache = {};
    
      factory Player(String name) {
        if (_cache.containsKey(name)) {
          return _cache[name]!;
        } else {
          final player = Player._internal(name);
          _cache[name] = player;
          return player;
        }
      }
    
      Player._internal(this.name);
    }
    

    👉 핵심: 동일 이름의 객체를 재사용하거나, 조건에 따라 다른 객체를 반환할 수 있음.


    3. @override로 메서드 재정의

    상속받은 메서드를 재정의해 클래스의 행동을 바꿀 수 있다.

    class Player {
      final String name;
      int xp;
    
      Player(this.name, this.xp);
    
      @override
      String toString() => "Player(name: $name, xp: $xp)";
    }
    
    void main() {
      var p = Player("jeongwon", 1500);
      print(p); // Player(name: jeongwon, xp: 1500)
    }
    

    👉 핵심: @override는 부모 메서드의 동작을 자식 클래스에서 재정의할 때 사용한다.


    4. 정리

    개념 설명 예시

    클래스 객체의 설계도 class Player {...}
    생성자 객체 초기화 Player(this.name)
    이름 있는 생성자 다양한 초기화 제공 Player.fromJson(...)
    이름 있는 매개변수 인자명 명시로 가독성 향상 {required this.name}
    초기화 리스트 본문 실행 전 필드 초기화 : name = n
    factory 생성자 캐싱, 조건 분기 등 factory Player(...)
    @override 상위 메서드 재정의 toString()

    오늘 느낀 점 ✍️

    오늘 배운 Dart의 클래스 문법은 다른 언어보다 간결하면서도 직관적이었다.
    특히 named parameters와 initializer list의 조합은 가독성과 안전성을 높여주는 구조라 실무에서도 자주 쓰일 것 같다.
    또한 factory 생성자를 통해 객체 생성 과정을 제어할 수 있다는 점이 흥미로웠다.

    '프론트 > Dart' 카테고리의 다른 글

    Dart# Fin. OOP 의 심화(상속, 추상, Mixin)  (0) 2025.10.07
    Dart#4. 문법 기초 정리 (Optional Parameters, Null Safety, Typedef)  (0) 2025.10.01
    Dart#3. 함수  (0) 2024.11.03
    Dart#2. 자료형  (0) 2024.10.29
    Dart #1. Hello World  (0) 2024.10.27
Designed by Tistory.