Dart 기초 - Constructor 생성하기
다음과 같은 방법으로 생성자를 만들 수 있다.
class Player {
late String name;
late int score;
Player(this.name, this.score);
}
void main() {
var player1 = Player("Lee", 20);
var player2 = Player("Kim", 30);
print(player1.score); // 20
print(player2.score); // 30
// you can change the value.
player2.score = 50;
print(player2.score);
}
코틀린과 유사하면서 조금 다른 모습을 볼 수 있다.
위 코드에선 생성자로 지정한 변수를 어느 타이밍에서든 변경할 수 있는데
변수에 final 처리를 해서 변경할 수 없게 만들 수 있다.
Named Constructor
Named Constructor를 사용하면 일부 생성자에 초기값을 지정할 수 있다.
사용 방법은 java에서 사용하는 생성자를 사용한 변수 지정과 유사한 형태를 보인다.
class Player {
late String name, team;
late int score;
Player(this.name, this.score);
// each team parameter has default value.
Player.createBlueTeam({required this.name, required this.score})
: this.team = "blue";
Player.createRedTeam({required this.name, required this.score})
: this.team = "red";
}
void main() {
var player1 = Player.createBlueTeam(name: 'Lee', score: 50);
var player2 = Player.createRedTeam(name: 'Kim', score: 50);
}
required를 사용해서 반드시 넣어줘야하는 파라미터를 지정하고
: 을 사용해서 각각의 파라미터의 기본값을 지정한다는 것이다.
API 데이터 받아서 클래스로 저장하기
일반적으로 API를 통해서 JSON 데이터를 받는데 이를 클래스로 만들어본다.
예시 데이터는 다음과 같고
var apiData = [
{"name": "Lee", "team": "red", "score": 0},
{"name": "Kim", "team": "blue", "score": 0},
{"name": "Park", "team": "green", "score": 0}
];
해당 데이터를 받는 클래스의 파라미터는 다음과 같다.
class Player {
late final String name;
late int score;
late String team;
}
다음과 같은 방법을 사용해서 Player 클래스에서 json 데이터를 받아서 프로퍼티로 넣어줄 수 있다.
class Player {
final String name;
int score;
String team;
// : 를 사용하여 프로퍼티를 초기화
Player.fromJson(Map<String, dynamic> playerJson):
name = playerJson['name'],
score = playerJson['score'],
team = playerJson['team'];
void hello() {
print("hello $name / $score / $team");
}
}
참고로 Player 클래스의 프로퍼티에 late를 붙여도 똑같이 동작한다.
class Player {
late final String name;
late int score;
late String team;
~~~~
}
이제 apiData를 Player 클래스에 넣어서 hello 함수로 출력해본다.
apiData에는 3개의 데이터가 있기 때문에 forEach를 사용해서 하나씩 출력하게 한다.
class Player {
late final String name;
late int score;
late String team;
// : 를 사용하여 프로퍼티를 초기화
Player.fromJson(Map<String, dynamic> playerJson):
name = playerJson['name'],
score = playerJson['score'],
team = playerJson['team'];
void hello() {
print("hello $name / $score / $team");
}
}
void main() {
var apiData = [
{"name": "Lee", "team": "red", "score": 0},
{"name": "Kim", "team": "blue", "score": 0},
{"name": "Park", "team": "green", "score": 0}
];
apiData.forEach((playerJson){
var player = Player.fromJson(playerJson);
player.hello();
});
}
// 출력결과
hello Lee / 0 / red
hello Kim / 0 / blue
hello Park / 0 / green
Cascade Notation
만약 클래스 인스턴스의 매개변수를 바꾸고 싶다면 어떻게 해야할까?
일반적인 방법으로 생각하면 다음과 같은 방법이 있다.
class Player {
late String name;
late int score;
late String team;
Player({
required this.name,
required this.score,
required this.team
});
}
void main() {
var player = Player(name: "lee", score: 20, team: "red");
// 각 요소를 하나씩 변경
player.name = "kim";
player.score = 30;
player.team = "blue";
}
위에서처럼 인스턴스의 각 요소를 변경하는 방법이 있지만
이를 조금 더 간단하게 표현할 수 있다. 이를 Cascade Notation이라고 한다.
void main() {
var player = Player(name: "lee", score: 20, team: "red")
// ..은 player를 의미한다.
..name = "kim"
..score = 30
..team = "blue";
// 이미 정의한 인스턴스라면 이렇게 할 수도 있다.
player
..name = "las"
..score = 50
..team = "red";
}
Enum
Enum을 사용하면 변수에 넣을 수 있는 값을 제한할 수 있다.
다음과 같은 방법으로 Enum을 정의하고 사용할 수 있습니다.
enum Team {
red,
blue
}
void main() {
var player = Player(name: "lee", score: 20, team: Team.red)
// ..은 player를 의미한다.
..name = "kim"
..score = 30
..team = Team.blue;
}
Abstract(추상화) 클래스
추상화 클래스는 일반적인 클래스처럼 값을 정의할 때 사용하는 것이 아니라
다른 클래스에 상속되어서 사용된다.
상속된 클래스는 반드시 추상 클래스가 가진 매개변수나 함수를 재정의(override) 해야한다.
예를 들면 다음과 같다.
abstract class Human {
void walk();
}
class Player extends Human {
late String name;
late int score;
late Team team;
Player({
required this.name,
required this.score,
required this.team
});
// @override 구문은 삭제해도 상관없다.
@override
void walk() {
print("player walking");
}
}
void main() {
var player = Player(name: "lee", score: 20, team: Team.red);
player.walk();
}
이처럼 특정 함수에서 특정 기능을 반드시 포함하거나 해야할 때 사용할 수 있는게 abstract class이다.
클래스 상속
객체지향 함수라면 반드시 알아야할 기능이 클래스 상속이다.
다음과 같은 클래스가 있다고 생각한다.
class Human {
final String name;
Human({required this.name});
void hello() {
print("my name is $name");
}
}
Human 클래스는 name이라는 매개변수를 필수로 받아야하며
Player 클래스에 다음과 같이 상속된다.
class Human {
final String name;
Human({required this.name});
void hello() {
print("my name is $name");
}
}
enum Team { red, blue }
class Player extends Human {
final Team team;
// 상속받은 Human에 name을 넘겨줘야하기 때문에 반드시 name을 받게한다.
Player({required this.team, required String name})
: super(name: name); // super를 통해 상속하는 클래스에 접근할 수 있다.
// override를 사용하면 함수도 재정의할 수 있다.
@override
void hello() {
super.hello();
print("my team is : ${team.name}");
}
}
extends를 사용해서 Human 클래스를 Player 클래스에 상속할 수 있으며
Human 클래스에서 필요로 하는 name을 넘겨주기 위해
Player 클래스에서도 name을 반드시 받아야하는 매개변수로 설정한다.
받은 name은 다음과 같이 supuer로 상속한 클래스에 매개변수로 넘겨줄 수 있다.
Player({required this.team, required String name})
: super(name: name);
상속한 클래스는 다음과 같이 사용할 수 있다.
class Human {
final String name;
Human({required this.name});
void hello() {
// my name is lee
print("my name is $name");
}
}
enum Team { red, blue }
class Player extends Human {
final Team team;
Player({required this.team, required String name})
: super(name: name);
@override
void hello() {
super.hello();
print("my team is : ${team.name}");
}
}
void main() {
var player = Player(
team: Team.red,
name: "lee"
);
player.team;
player.name;
// my team is : red
player.hello();
}
Mixins 클래스
Mixins 클래스는 생성자가 없는 클래스를 의미하며
Mixins 클래스를 사용하면 해당 클래스 내에 정의된 모든 요소를 가져와서 사용할 수 있다.
다음과 같이 다수의 클래스를 정의한다.
class Strong {
final double power = 1500.55;
}
class Runner {
void run(){
print("run!");
}
}
class Tall {
final double height = 1.75;
}
이를 with을 사용하여 Player에 삽입한다.(Mixins)
class Player with Strong, Runner, Tall {
final Team team;
Player({required this.team});
}
이렇게 하면 Player로 만든 모든 인스턴스는 with에 들어있는 클래스의 모든 요소를 사용할 수 있게 된다.
void main() {
var player = Player(team: Team.blue);
// with으로 처리된 모든 클래스에 있는 기능을 사용가능
player.height;
player.power;
player.run();
}
'플러터(flutter)' 카테고리의 다른 글
VS 코드에서 플러터 사용 설정 - 파란색 줄 없애기 등... (0) | 2023.04.15 |
---|---|
플러터 기초 - UI 구성 (0) | 2023.04.15 |
Dart 기초 - 함수 (0) | 2023.04.05 |
Dart 기초 - 컬렉션(Collections) (0) | 2023.04.04 |
Dart 기초 - 변수 선언하기 (0) | 2023.04.02 |
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
댓글