[Dart 기초] 클래스

지은·2023년 11월 2일
0

Dart/Flutter

목록 보기
3/5

Dart는 객체 지향 프로그래밍 언어로, 클래스와 객체 지향 프로그래밍 개념을 지원한다.
클래스는 객체를 생성하기 위한 청사진, 객체는 클래스의 인스턴스이다.

Class

Dart에서 클래스를 정의하는 법은 다음과 같다.

class 클래스명 {
  // 멤버 변수(field) 정의
  // 생성자(constructor) 정의
  // 메소드(method) 정의
}

멤버 변수(Fields)

: 클래스 내부에 정의된 변수
해당 클래스의 인스턴스(객체)가 가지는 데이터로, 다른 객체와 데이터를 공유하지 않고 각 객체가 고유한 값을 갖는다. 초기값을 가질 수 있다.

class Player {
  String name = '지은'; // 멤버 변수
  int age = 27;        // 멤버 변수
}

void main() {
  var player1 = Player();
  print(player1.name); // 지은
}

메소드(Methods)

: 클래스 내부에 정의된 함수
Dart에서this 키워드는 현재 객체(인스턴스)를 가리키는 데 사용하며, this를 사용하여 현재 객체의 멤버 변수나 메소드에 접근할 수 있다. this는 생략할 수 있다.

class Player {
  final String name = '지은';
  int age = 27;
  
  void sayHello() { // 메소드
    print('Hello, my name is $name');
  }
}

void main() {
  var player1 = Player();
  player1.sayHello(); // Hello, my name is 지은
}

생성자(Constructor)

클래스가 객체를 생성할 때 초기화할 때 사용되며, 주어진 데이터를 클래스의 멤버 변수에 할당하는 역할을 한다.
클래스 생성자를 정의하는 방법은 아래와 같다.

class 클래스명 {
  // 멤버 변수 정의
  
  // 생성자 정의
  클래스명(파라미터1, 파라미터2...) {
    // 생성자에서 멤버 변수 초기화
  }
}

아래의 코드에서 Player 클래스는 nameage라는 멤버 변수를 가지고 있으며, 생성자는 파라미터를 받아와 멤버 변수에 할당한다.

class Player {
  late final String name;
  late int age; // late 키워드는 값을 나중에 받아오는 것을 허용
  
  Player(String name, int age) { // 생성자
    this.name = name;
    this.age = age;
  }
}

void main() {
  var player1 = Player('지은', 27);
  print(player1.name); // 지은
 
  var player2 = Player('지지', 13);
  print(player2.name); // 지지
}

생성자 파라미터는 두 가지 방식으로 정의할 수 있다.

1. Positional Constructor Parameters

: 생성자 호출 시 매개변수의 위치(순서)를 기준으로 값을 전달하는 방법
Positional parameters를 사용하려면 생성자 선언 시 매개변수를 그냥 나열하면 된다.

class Player {
  final String name; // 멤버 변수
  int age;
  bool isAdult;
  
  void sayHello() { // 메소드
    print('Hello, my name is $name');
  }
  
  Player(this.name, this.age, this.isAdult); // 생성자
}


void main() {
  var player1 = Player('지은', 27, true);
  var player2 = Player('지지', 13, false);
  
  print(player1.name); // 지은
  print(player2.name); // 지지
}

2. Named Constructor Parameters

: 생성자 호출 시 매개변수의 이름과 값을 명시적으로 지정하여 값을 전달하는 방법
Named parameters를 사용하려면 생성자 선언 시 매개변수를 중괄호({})로 감싸주면 된다.
필요한 경우, required 키워드를 사용해 null 에러를 방지할 수 있다.

class Player {
  final String name;
  int age;
  bool isAdult;
  
  Player({required this.name, required  this.age, required this.isAdult});
}


void main() {
  var player1 = Player(
    name: '지은', 
    age: 27, 
    isAdult: true
  );
 
  var player2 = Player(
    name: '지지', 
    age: 13, 
    isAdult: false
  );
  
  print(player1.name); // 지은
  print(player2.name); // 지지
}

이름 있는 생성자(Named Constructor)

: 클래스 내에 여러 생성자를 정의할 때 사용하며, 생성자를 호출할 때 생성자의 이름을 명시적으로 지정하는 방식이다.

Named Constructor는 클래스 이름 다음에 .constructorName 형식으로 작성하고, 중괄호({}) 내부에 필요한 매개변수를 작성하면 된다.
Named Constructor는 기본 생성자와 다르게 이름을 가지고 있으며, 이를 통해 여러 생성자 시나리오를 만들 수 있다.
Named Constructor를 정의하는 방법은 아래와 같다.

class 클래스명 {
  // 멤버 변수(field) 정의
  
  // 기본 생성자(unnamed constructor) 정의
  클래스명(파라미터1, 파라미터2...) {
    // 생성자에서 멤버 변수 초기화
  }
  
  // named constructor 정의
  클래스명.생성자명({ 생성자 파라미터1, 생성자 파라미터2... }) {
    // 생성자에서 멤버 변수 초기화
  }
}

예시

아래 코드에서 Player 클래스는 Player.createBluePlayerPlayer.createRedPlayer 두 개의 Named Constructor를 가지고 있으며,

createBluePlayer 생성자는 인스턴스를 생성할 때, team 값을 "blue"로 초기화하고, createRedPlayer 생성자는 team 값을 "red"로 초기화한다.

class Player {
  final String name;
  int age;
  String team;
  
  Player({
    required this.name, 
    required this.team,
    required this.age, 
  });
  
  Player.createBluePlayer({
      required String name, 
      required int age
    }) : this.name = name, // 클래스를 초기화
         this.age = age,
         this.team = 'blue'; // 기본값을 줄 수 있다.
    
   Player.createRedPlayer({
      required String name, 
      required int age
    }) : name = name, // 클래스를 초기화
         age = age,
         team = 'red'; // 기본값을 줄 수 있다.
}

void main() {
  var player1 = Player.createBluePlayer(
    name: '지은', 
    age: 27,
  );
 
  var player2 = Player.createRedPlayer(
    name: '지지', 
    age: 13, 
  );
  
  print(player1.name); // 지은
  print(player2.name); // 지지
}

이렇게 Named Constructor를 사용하면 객체 초기화를 더 명확하게 정의할 수 있고, 다양한 초기화 옵션을 제공할 수 있다.

콜론(:)

Dart에서 콜론(:)은 주로 초기화 목록(Initialization List)나 부모 클래스의 생성자를 호출하는 데 사용된다.

초기화 목록(Initialization List)

: 생성자 내부에서 클래스의 멤버 변수를 초기화하는 특별한 구문으로 생성자의 중괄호({}) 이전에 작성된다.
초기화 목록을 사용하여 객체의 멤버 변수를 초기화하고, 생성자 본문 내에서 초기화하지 않고도 변수를 설정할 수 있다.

class ClassName {
  final String field1;
  int field2;

  // 생성자
  ClassName(
    this.field1, 
    this.field2
  ) : field2 = field2 * 2, 
      field1 = 'Hello';
}

위의 코드에서 field1field2라는 멤버 변수가 있고, 생성자에서 이 변수들을 초기화하는데, 이때 초기화 목록을 이용해서 field2를 2배로 곱하고, field1을 'Hello'로 설정하고 있다.

이렇게 초기화 목록을 사용하면 생성자 본문 내에서 변수를 초기화할 필요 없이 필드를 초기화할 수 있어 더 효율적이다.

예시2

아래 코드는 API 요청을 통해 받아온 JSON 데이터를 Named Constructor를 이용해 Player 객체로 변환하는 예시이다.
Dart에서 데이터를 객체로 변환하는 데 자주 사용되는 패턴이다.

class Player {
  final String name;
  int age;
  String team;
  
  void sayHello() {
    print('Hi, my name is $name');
  }
  
  // JSON 데이터를 Player 객체로 변환하는 목적으로 정의된 Named Constructor
  // Map<String, dynamic> 형식의 playerJson 매개 변수를 받는다.
  Player.fromJson(Map<String, dynamic> playerJson) :
    name = playerJson['name'], // 매개변수를 사용해 멤버 변수를 초기화한다.
    age = playerJson['age'],
    team = playerJson['team'];
}

void main() {
  var apiData = [
    {
      'name': '지은',
      'age': 25,
      'team': 'blue',
    },
    {
      'name': '지지',
      'age': 13,
      'team': 'red',
    },
    {
      'name': '벨라',
      'age': 11,
      'team': 'red',
    },
  ];
  
  // forEach를 이용해 apiData 리스트의 각 JSON 객체를 순회하고,
  // 각 JSON 객체를 Player.fromJson 생성자를 사용해 Player 객체로 변환한다.
  apiData.forEach((playerJson) {
    var player = Player.fromJson(playerJson);
    player.sayHello(); // 변환된 Player 객체에 sayHello() 메소드를 호출하여 메세지를 출력한다.
    // Hi, my name is 지은
	// Hi, my name is 지지
	// Hi, my name is 벨라
  });
}
profile
블로그 이전 -> https://janechun.tistory.com

4개의 댓글

comment-user-thumbnail
2023년 11월 12일

정리가 항상 잘되있으셔서 보기 편합니다 !

답글 달기
comment-user-thumbnail
2023년 11월 12일

묘하게 타입스크립트를 통해 클래스를 선언하는 방법이랑 비슷한듯 하면서도 좀 다르군요! 언젠가 Flutter를 통해서 네이티브 앱도 만들어보고 싶었는데 재밌게 잘 읽었습니다!

답글 달기
comment-user-thumbnail
2023년 11월 12일

자바스크립트 클래스로 만드는 객체지향이랑 많이 비슷한거 같네여! 잘읽고 가용~

답글 달기
comment-user-thumbnail
2023년 11월 12일

크 객체 지향 언어인 다트의 진가가 여기서 나오죠. 플러터 하면서 JS보다 더 배운 거 같아요 ㅋㅋㅋ 잘보고 갑니당

답글 달기