Dart Class, enum, mixin

Byeonggwan Kang·2023년 3월 30일
0

dart, flutter and modes

목록 보기
6/9

Dart의 클래스, 상속, enum, mixin 등에 대해 설명한다.

  • Class, enum
  • Abstract class
  • Inheritance
  • Mixin

이번엔 내가 좋아하는 게임으로 클래스를 만들어보겠다. 구조는 다음과 같다. LoLGamer 클래스를 만드는 과정에 집중한다.

Abstract Class

우선 Gamer에 필요한 id와 생성자, 그리고 이를 상속받을 클래스가 구현할 함수 play를 만들었다.

abstract class Gamer {
  String id;

  Gamer({required this.id});
  void play();
}

자세한 설명은 생략한다.


Enum

롤, 히오스에는 챔피언과 영웅이 있기 때문에 Enum을 사용해서 구현하겠다. Enum을 사용할 경우 String을 직접 쓸 때보다 실수 할 여지도 줄어들고, Dart에서는 Class처럼 사용 가능하기 때문에 더 편리하다고 본다.

enum Champs {
  garen(
    name: '가렌',
    skills: [
      '결정타',
      '용기',
      '심판',
      '데마시아의 정의',
    ],
  ),
  teemo(
    name: '티모',
    skills: [
      '실명 다트',
      '신속한 이동',
      '맹독 다트',
      '유독성 함정',
    ],
  );

  final String name;
  final List<String> skills;

  const Champs({required this.name, required this.skills});
}

enum Hero {
  valla('발라'),
  // ...이하생략
}

void main() {
  var teemoUser = Champs.teemo;
  print('멋쟁이 ${teemoUser.name}');
  print(teemoUser.skills);
}


출력
멋쟁이 티모
[실명 다트, 신속한 이동, 맹독 다트, 유독성 함정]

Dart 최근 버전에서는 다음과 같이 enum을 사용할 수 있다. 생성자와 매개변수를 사용해서 enum안의 element를 정의했다. Class와 별 다를 것이 없으므로 메소드와 상속도 사용할 수 있다. 참고로 enum의 원소들은 컴파일 전에 결정되므로 반드시 생성자를 const로 선언해야 한다.

enum Lane {
  top('탑'),
  mid('미드');

  final String toKorean;

  const Lane(this.toKorean);
}

LoLGamer에 사용할 Lane도 만들었다.


Inheritance

Gamer를 상속받는 두 클래스를 구현한다.

class LoLGamer extends Gamer {
  final Champs champion;
  final Lane lane;

  LoLGamer({required this.champion, required this.lane, required String id})
      : super(id: id);

  
  void play() {
    print('저는 롤 ${lane.toKorean} ${champion.name} 유저입니다.');
  }
}

class HosGamer extends Gamer {
  final Hero hero;

  HosGamer({
    required this.hero,
    required String id,
  }) : super(id: id);

  
  void play() {
    print('전 히오스 ${hero.name} 유저입니다.');
  }
}

상속은 java처럼 super로 부모 클래스의 생성자를 불러오고, @override하는 식으로 진행된다. 한 가지 알아야 할 사실은 Dart가 다중 상속을 지원하지 않는다는 것이다. 이 점을 보완하기 위해 mixin은 지원한다.


Mixin

위 예시 그림에서 account와 korean처럼, 다른 곳에 재사용이 많이 되며 '굳이 이 클래스에서 구현해야 할까?'하는 부분은 mixin을 이용한다.

class Korean {
  final String region = 'Korea';
}

class Account {
  // 예시
  void login() => print('login');
  void logout() => print('logout');
}

class LoLGamer extends Gamer with Account, Korean {
  ...
}

class HosGamer extends Gamer with Account, Korean {
  ...
}

with Mixin을 사용하면 LoLGamer 클래스에서 region, login(), logout()을 사용할 수 있다. 주의해야 할 점은 mixin에는 생성자가 없어야 한다는 점이다. 상속이 아닌 만큼 그 클래스와 관련있지만 거기서 구현하기엔 애매한 그런 부가적인 기능에 사용하는 것 같다.

// 위 구현을 마침
void main() {
var teemoPlayer = LoLGamer(
    champion: Champs.teemo,
    lane: Lane.top,
    id: 'teemoKing',
  )
    ..login()
    ..play()
    ..logout();

  print(teemoPlayer.region);
}


출력
login
저는 롤 탑 티모 유저입니다.
logout
Korea

최대한 재사용 가능성에 초점을 두고 구현해보자.

0개의 댓글