본문 바로가기
기초다지기/Flutter&Dart

Dart Class

by 김빵그 2023. 4. 6.

1. 기본 클래스 구조

class Player {
  String name = "songyi";
  int xp = 1500;
}

void main() {
  var player = Player();
  print(player.name);
  player.name = "lalalal";
  print(player.name);
  //songyi
  //lalala
}
  • Flutter에서는 모든게 class다
  • class에서 property를 선언할 때는 타입을 사용해서 정의한다
class Player {
  final String name = "songyi";
  int xp = 1500;

  void sayHello() {
    var name = "newname";
    print("hi~ my name ${this.name}");
  }
}

void main() {
  var player = Player();
  player.sayHello();
  //hi! my name songyi
}
  • class에 name을 바꾸지 않게 하려면 final을 입력한다 > 수정 재 정의 불가
  • class method 내에서의 this는 사용하지 않는 것을 권고되고 있다
  • variable과 class property의 이름이 겹치는게 아니라면 this를 쓰지 않는다

 


2. constructors (생성자)

 

class Player {
  late final String name;
  late int xp;

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

  void sayHello() {
    print("hi~ my name $name");
  }
}

void main() {
  var player = Player("songyi", 1500);
  player.sayHello();
  var player2 = Player("psj", 2500);
  player2.sayHello();
  //hi~ my name songyi
  //hi~ my name psj
}
  • late는 변수들의 값을 나중에 받아올것을 의미한다
  • 위의 코드를 좀 더 깔끔하게 다듬는다면 아래와 같은 코드로 변경 
class Player {
  final String name;
  int xp;

  Player(this.name, this.xp);

  void sayHello() {
    print("hi~ my name $name");
  }
}

void main() {
  var player = Player("songyi", 1500);
  player.sayHello();
  var player2 = Player("psj", 2500);
  player2.sayHello();
  //hi~ my name songyi
  //hi~ my name psj
}
  • late를 지우고 사용자가 보낸 argument(name과 xp가) 되므로 this를 붙여 constructor 코드를 좀 더 다듬었다.
  • late는 꼭 필요한 경우에만 사용을 하라고 명시되어있다 contructor 생성시 변수에 값을 할당하지 않고 즉시 프로퍼티에 값을 담아주고 있기 때문에 late는 지워준다

 


3. named constructor parameters

class Player {
  final String name;
  int xp;
  String team;
  int age;

  Player({
    required this.name,
    required this.xp,
    required this.team,
    required this.age,
  });
}

void main() {
  var player = Player(
    name: "songyi",
    xp: 2000,
    team: 'red',
    age: 20,
  );
  var player2 = Player(
    name: "psj",
    xp: 2200,
    team: 'blue',
    age: 22,
  );
 
}
  • 너무 많은 Position argument가 있으면 혼란스러워진다. 위치에 따라 무엇을 정의하는지 확인하는 불편함이 있으므로 네임 전달인자를 가진 생성자로 바꾸는게 좋다
  • 타입을 선언한 후 > 생성자에 {} 중괄호를 이용한다. 이후 변수parameter가 null일수도 있기 때문에 required나 기본값을 줘서 처리해준다 > 데이터가 많은 클래스들을 만날때도 key : value값을 작성해주면 된다
  • Player({...}) = named constructor prameter (네임 매개변수 생성자)

 


4. named constructor

class Player {
  final String name;
  int xp, age;
  String team;

  Player({
    required this.name,
    required this.xp,
    required this.team,
    required this.age,
  });
  Player.createBluePlayer({
    required String name,
    required int age,
  })  : this.age = age,
        this.name = name,
        this.team = 'blue',
        this.xp = 0;

  Player.createRedPlayer(
    String name,
    int age,
  )   : this.age = age,
        this.name = name,
        this.team = 'red',
        this.xp = 0;

  void sayHello() {
    print("hi~ my name $name");
  }
}

void main() {
  var player = Player.createBluePlayer(
    name: 'songyi',
    age: 20,
  );
  var redplayer = Player.createRedPlayer(
    'psj',
    22,
  );
}
  • createBluePlayer라는 새로운 메서드를 만든 후 name과 age 파라미터를 받고 : 콜론을 사용하여 클래스 player를 초기화 시켜준다
  • blue는 named red는 position 생성자인데 position은 하나라도 안 들어가면 에러가 뜬다. name은 required를 명시해줘야 한다

 

class Player {
  final String name;
  int xp;
  String team;

  Player.fromJson(Map<String, dynamic> playerJson)
      : name = playerJson['name'],
        xp = playerJson['xp'],
        team = playerJson['team'];
  void sayHello() {
    print("hi~ my name $name");
  }
}

void main() {
  var apiData = [
    {
      "name": 'songyi',
      "team": "red",
      "xp": 0,
    },
    {
      "name": 'psj',
      "team": "red",
      "xp": 110,
    },
    {
      "name": 'kth',
      "team": "blue",
      "xp": 30,
    },
  ];
  for (var playerJson in apiData) {
    var player = Player.fromJson(playerJson);
    player.sayHello();
  }
}
  • 만약 api data를 가져와서 활용시에는 위와 같이 사용하면 된다
  • apidata를 가져와 이름이 Player.fromJson인 constructor을 생성 > Map argument를 받는다.
  • 그리고 : 을 추가하여 프로퍼티를 초기화 시켜준다 (..어렵다..)

 


5. Cascade notation

void main() {
  var songyi = Player(name: "songyi", xp: 122, team: 'red');
  songyi.name = 'psj';
  songyi.xp = 300;
  songyi.team = 'blue';
}
/////아래와 같이 변경 가능하다

void main() {
  var songyi = Player(name: "songyi", xp: 122, team: 'red')
  ..name = 'psj'
  ..xp = 300
  ..team = 'blue'; 
}
  • songyi.라는 코드를 반복하는 대신 ; 세미콜론을 없앤 후  ..(cascade operator)을 사용할 수 있다

 


6. Enums 

enum Team {red, blue}
enum XPLevel {beginer, medium, pro}
class Player {
  String name;
  XPLevel xp;
  Team team;
}

void main() {
  var songyi = Player(name: "songyi", xp: XPLevel.beginer, team: Team.red)
  ..name = 'psj'
  ..xp = XPLevel.pro
  ..team = Team.red; 
}
  • 오타 같은 실수 하지 않게 도와주는게 바로 Enums이다
  • 선택의 폭을 좁혀주는 역할을 함
  • ""텍스트 형태로 적을 필요가 없다

 


7. abstract class (추상화 클래스)

abstract class Human {
  void walk();
}

class Coach extends Human {
  @override
  void walk() {
    print("coach is wolking");
  }
}
  • 추상 클래스는 다른 클래스들이 직접 구현해야 하는 필드와 메소드들을 모아놓은 클래스이다
  • 추상화 클래스로는 메소드와 내용이 추상적이므로 객체를 생성할 수 없다
  • 추상 클래스를 상속받는 클래스들은 추상 클래스의 메소드를 구현해야한다
  • Human이라는 추상화 클래스는 walk라는 메소드를 가지고, walk라는 메소드는 void를 반환해야 한다
  • 다른 클래스에서 extends  상속, 확장 할 수 있다

 


8. inheritance 상속

class Human {
  final String name;
  Human({required this.name});
  void sayHello() {
    print("hi my name is $name");
  }
}

enum Team { blue, red }

class Player extends Human {
  final Team team;

  Player({required this.team, required String name}) : super(name: name);

  @override
  void sayHello() {
    super.sayHello();
    print('and i Play for ${team}');
  }
}

void main() {
  var player = Player(team: Team.blue, name: "songyi");
  player.sayHello();
}
  • 상속을 한 후 super를 이용해 부모 클래스의 생성자를 호출할 수 있다

 


9. Mixins

class Strong {
  final double strenghtLevel = 1500.99;
}
class QuickRunner {
  void runQuick() {
    print('ruuuun ');
  }
}
class Tall {
  final double height = 1.88;
}

enum Team { blue, red }

class Player with Strong, QuickRunner, Tall {
  final Team team;

  Player({
    required this.team,
  });
}
  • mixin은 생성자가 없는 클래스를 의미한다
  • 위 String은 클래스이고 어떠한 생성자도 가지고 있지 않다
  • 여러 클래스에 재사용이 가능하다
  • extend랑은 다르다 extend를 하게 되면 확장한 그 클래스는 부모 클래스가 되는 것이고, 자식 클래스는 부모 클래스를 super를 통해 접근할 수 있고 그 순간 부모 클래스의 인스턴스가 된다
  • with는 단순히 mixin 내부의 프로퍼티와 메소드들을 가져오는 것 뿐이다. 부모 클래스가 되거나 하지는 않음

 

 

 

 

 

https://nomadcoders.co/dart-for-beginners/lectures/4113

'기초다지기 > Flutter&Dart' 카테고리의 다른 글

Dart Set에 대해 알아보자  (0) 2023.04.07
Dart List  (0) 2023.04.06
Flutter / Dart 빌드  (0) 2023.04.05
Dart functions  (1) 2023.04.05
Dart Data types  (0) 2023.04.04