Dart에서 클래스는 어떻게 사용할까?
기본적인 클래스 및 생성자 구조와 다양한 속성들에 대해 기록하였다.
Basic Class
class Player {
// Class에서 property를 정의할 때는 Type을 지정해준다.
String name = "JP"; // 외부에서 이름 변경 가능
final String name = "JP"; // 이러면 외부에서 이름 못바꿈
int xp = 1500;
void sayHello() {
var name = "JPJP";
// Dart의 클래스에서는 this를 사용하지 않는다. $this.name이 아닌 그냥 $name을 사용
print("Hi my name is $name");
// 만약 함수 내부에 새로운 name이 정의되었고 이를 사용하려면 아래와 같이 사용한다.
print("Hi my name is ${this.name}")
}
}
void main() {
var player = Player();
player.name; // JP
player.xp; // 1500
}
Constructors
class Player {
late final String name;
int xp;
// Dart에서 Constructor는 아래와 같이 정의
Player(String name, int xp) {
this.name = name;
this.xp = xp;
}
// 위 Player Constructor와 같음
Player(this.name, this.xp);
}
void main() {
var player = Player("JP", 31);
}
Named Constructor Parameters
class Player {
late final String n ame;
int xp, age;
String team;
// 위 Player Constructor와 같음
// 이러면 각 인자가 null로 들어올 수 있다고 에러가 난다.
// default 값을 정해주거나, required 수식어를 붙여준다.
Player({this.name = "Default", required this.xp, required this.team, required this.age});
}
void main() {
// 아래 방법은 positional 이므로 함수처럼 optional로 설정 가능하다.
var player = Player("JP", 31, "red", 12);
// optional
var player = Player(name:"JP", age:12, team:"red", xp:31);
}
Named Constructor
class Player {
late final String name;
int xp, age;
String team;
Player({
required this.name,
required this.xp,
required this.team,
required this.age
});
// 아래와 같은 코드로 용도에 맞는 생성자를 구성할 수 있다.
// ':'을 사용함으로써 Player 객체를 원하는 설정에 맞게 초기화하는 것으로 이해하자.
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 main() {
var bluePlayer = Player.createBluePlayer(name:"JP", age:21);
var redPlayer = Player.createRedPlayer("EL", 23);
}
Cascade Notation
class Player {
late final String name;
int xp, age;
String team;
Player({
required this.name,
required this.xp,
required this.team,
required this.age
});
}
void main() {
// 생성자 인스턴스를 만들고 맨 마지막에 세미콜론을 생략한 채 .. + 속성에 접근하여 수정할 수 있다.
// 이것이 바로 Cascade Notation이다
var user = Player(name:"JP", xp:0, team:"blue", age:21)
..name = 'EL'
..xp = 9999
..team = 'red';
}
Enums
// Enum을 지정해줌으로써 파라미터를 잘못 넘기는 것을 방지해준다.
// 마치 TypeScript에서 인자로 받을 수 있는 파라미터를 지정해 주는 것과 같다.
enum Team {red, blue}
class Player {
late final String name;
int xp, age;
// enum으로 정의된 Team을 타입으로 설정했기 때문에 team은 red or blue만 받을 수 있다.
Team team;
Player({
required this.name,
required this.xp,
required this.team,
required this.age
});
}
void main() {
var user = Player(name:"JP", xp:0, team:"blue", age:21)
..name = 'EL'
..xp = 9999
..team = Team.blue; // 변경도 enum 범위 안에서 변경해야 한다.
}
Abstract Classes
// Human 추상 클래스는 walk라는 메서드를 가지고 있다.
// 기능이 정의되지는 않았지만 일반 클래스에서 Human 추상메서드를 구현하면 walk 메서드를 꼭 구현해야한다.
abstract class Human {
void walk();
}
class Player extends Human {
// extends는 상속이기 때문에 walk 함수의 내용이 채워져 있다면 재정의를 하지 않아도 된다.
// 그러나 이번 케이스에서는 Human -> walk 메서드가 정의만 되어있어서 재정의 필요
void walk() {
print('im walking');
}
}
class Coach implements Human {
// implements는 인터페이스 구현이기 때문에 무조건 walk 메서드 재정의가 필요하다.
void walk() {
print('the coach is walking');
}
}
Inheritance
class Human {
final String name;
Human(this.name);
void sayHellao() {
print('Hi my name is $name');
}
}
enum Team {red, blue}
class Player extends Human {
final Team team;
// 생성자 뒤에 : super 키워드를 통해 부모 클래스와 상호작용 할 수 있다.
Player({
required this.team,
required String name
}) : super(name);
// override 키워드 안써줘도됌.
@override
void sayHello() {
super.sayHello();
print("and I play for ${team}");
}
}
void main() {
var player = Player(team:Team.red, name:'JP');
player.sayHello();
}
Mixins
enum Team {red, blue}
// mixin은 아래와 같이 선언한다.
// 생성자가 존재하지 않아야 한다.
mixin Strong {
final double strengthLevel = 1500.99;
}
mixin QuickRunner {
void runQuick() {
print("runnnnnn!");
}
}
mixin Tall {
final double height = 1.99;
}
// mixin 클래스를 사용하려면 with 키워드를 사용한다.
class Player with Strong, QuickRunner, Tall {
final Team team;
Player({
required this.team,
required String name
});
}
class Horse with Strong, QuickRunner {
//...
}
void main() {
var player = Player(name:"JP", team:Team.red);
//player는 Player 클래스 인스턴스이면서 QuickRunner mixin 클래스를 사용하므로 runQuick 함수 사용이 가능하다.
player.runQuick();
}