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 |