클래스는 앞에 클래스를 명시해주고 뒤에 클래스명을 기입
class Player {
}
일반적인 클래스 생성 문법
: var player = Player();
: 프로퍼티 값은 초기화된 상태여야 함
class Player {
// class내부에서는 타입을 꼭 명시해주어야 함
String name = 'neander';
int xp = 1500;
// name은 현재 바꿀 수 있는데 바꾸고 싶지 않은 경우
final name1 = ''
// class method에서는 this.name이렇게 'this' 사용하는 것을 권장하지 않는다
void sayHello() {
print("Hi my name is $name")
}
}
void main() {
var player = Player(); // 앞에 new를 붙일 필요 없다(붙여도 상관없다)
print(player.name);
player.name = 'lalala';
print(player.name); // changed
}
Positional Arguments
: 순서대로 파라메터 값을 기입해야한다.
: 프로퍼티 값은 나중에 초기화 되기 떄문에 'late'를 사용한다.
: 클래스 내에서 this는 권장하지 않지만, 사용해도 무방하다.
// late를 사용해서 property들을 대기 시킨다.
// class에 parameter arguments넣기
class Player {
late final String name;
late int xp;
// constructor: 전형적인 방법이지만... Dart에서는 더욱 간단한 constructor가 있다.
Player(String name, int xp) {
this.name = name;
this.xp = xp;
}
void sayHello() {
print("Hi my name is $name");
}
}
: this.name = name; 이렇게 명시적 초기화를 할 수 있지만,
: 생성자 파라메터 내에서 선언 해주어 더욱 간결하게 만들 수 있다.
// dart에서 더욱 간단한 constructor 만드는 것
// late를 사용하지 않고 property들에게 바로 init을 시켜줄 수 있다.
class Player {
final String name;
int xp;
// 파라메터의 property값을 넣어주면 외부에서 해당 위치에 선언시
// 바로 적용이 된다. positional arguments 값을 넣는 위치가 중요하다.
Player(this.name, this.xp);
void sayHello() {
print("Hi, my name is $name");
}
}
void main() {
var player = Player('neander', 30);
player.sayHello();
}
Named Arguments
: 일반 함수에 명시 해주는 것처럼 '중괄호'를 사용한다.
: 생성자에 블럭으로 처리하지 않고 ':' 뒤에 콜론을 사용하여 표현할 수 있다.(훨씬 명료해보임, 끝에 ';' 세미콜론으로 마무리)
// positional arguments가 많아지면 헷갈려 진다.
class Player {
// {} 중괄호로 감싸주면 된다.
final String name;
int xp;
Player({this.name, this.x}); // 하지만 이렇게 하면 null safety로 인해 null체크를 해주어야 한다.
Player({required this.name, required this.xp}); // required를 넣어주어야 한다.
}
다르게 constructor을 생성하는 방법
class Player {
final String name, team;
int xp, age;
// 블루팀이지만 값은 '0'인 생성자
// Dart 고유 특징.. ':' 생성자 맨 뒤에 콜론':'만을 사용한다
// 그리고 끝에 ';'세미콜론으로 끝내준다.
Player.createBluePlayer({required String name, required int age}) :
this.age = age,
this.name = name,
this.team = 'blue',
this.xp = 0;
// no named parameter
Player.createRedPlayer(String name, int age) :
this.age = age,
this.name = name,
this.team = 'red',
this.xp = 0;
}
constructor응용
: Map을 사용해서 값을 넣고, 해당 값이 잘 표출되는지 확인
void main() {
var apiData = [
{
"name":"neander",
'team': 'red',
'xp': 0
},
{
"name":"hong",
'team': 'red',
'xp': 0
},
{
"name":"kk",
'team': 'red',
'xp': 0
}
];
apiData.forEach((playerJson) {
var player = Player.fromJson(playerJson);
player.sayHello();
});
}
// 위의 값들을 Player class로 묶어줄 것
class Player {
final String name;
int xp;
String team;
// ':' immediately init
Player.fromJson(Map<String, dynamic> playerJson) :
name = playerJson['name'],
xp = playerJson['xp'],
team = playerJson['team'];
void sayHello() {
print("Hi, my name is $name");
}
}
Cascade Operator
: kotlin의 scope function과 유사하다.
: 코드 수정을 상당히 간결하게 해주고, 인스턴스를 연속해서 호출하지 않기 때문에 매우 간결하고 눈이 편안하다..^^
: 객체 뒤에 ' .. ' 을 사용한다. 쩜쩜~ 그리고 해당 객체의 프로퍼티, 함수를 호출하여 사용한다.
class Player {
final String name;
int xp;
String team;
Player({
required this.name,
required this.xp,
required this.team
});
void sayHello() {}
}
// 위와 같은 경우 생성했을 때 더욱 명료하게 코드를 작성할 수 있음
// Cascade operator
void main() {
var player = Player(name: 'neander', xp: 30, team: 'red');
// player 생성자를 만든 다음, 값을 수정하고 싶은 경우
player.name = 'kk';
player.xp = 26;
player.team = 'green'; // 이렇게 바꿔주어야 한다.
// 하지만 dart에서는 kotlin의 scope function처럼 앞의 'player'를 연속적으로 사용하지 않는 문법이 있다.
// ..은 player1을 가르킨다.
var player1 = Player(name: 'hong', xp: 32, team: 'yellow')
..name = 'zz';
..xp = 1400;
..team = 'blue';
// 생성자를 만든 뒤에도 사용할 수 있다.
// 그리고 갖고 있던 함수도 사용할 수 있다.
var player2 = Player(name: 'greenman', xp:58, team: 'fall');
var bluo = player2
..name = 'yy'
..xp = 54
..sayHello();
}
enum class
: 개발자들이 실수하지 않도록 도와줌
: 오타를 줄일 수 있다
: enum 클래스명
enum Team {
red,
blue
} // red, blue라는 새로운 타입을 만든 것
class Player {
final String name;
int xp;
Team team; // Team이라는 enum class로 훨씬더 안전하게 만듦, 오타를 줄일 수 있지~~
Player({
required this.name,
required this.xp,
required this.team
})
}
void main() {
// Team.blue라는 enum class로 명확하게 명시를 해줄 수 있어서 안전하고 좋다.
var player = Player(name: 'neander', xp: 30, team: Team.blue);
}
abstract class, 추상 클래스
: 추상 클래스는 설계 도면이라고 생각하면 된다.
: 추상 클래스를 보고서 클래스를 만드는 느낌
: 그래서 꼭 필요한 프로퍼티나 함수를 잊지 않고 재정의 할 수 있다.
// 추상화는 클래스를 생성할 수 없고
// 다른 클래스들이 직접 구현 해야하는 메서드들 모아 놓음
abstract class Human {
void walk();
}
// 그럼 Human이라는 설계도를 extends한 클래스는 Human 추상화 클래스가 갖고 있던
// 프로퍼티, 함수들을 모두 내려 받아서 재정의하여 사용해야 한다.
class Player extends Human {
void walk() {
print('Im walking');
}
}
class Coach extends Human {
void walk() {
print('the coach is walking');
}
}
상속, extends
: 상속하는 클래스를 그대로 가져다 사용할 수 있다.
: 흔히 부모라고 하고, 그 부모에서 허용하는 범위내 프로퍼티, 함수 모두 사용할 수 있다.
: 부모에 접근하려면 'super'를 사용하여 접근하고
: 부모 생성자도 선언해야 하므로 본인 생성자 뒤에 콜론 ':' 을 붙이고 super를 사용하여
: 부모 생성자도 생성해준다.
// extends
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;
// Human의 생성자도 생성해주어야 한다.
// 콜론을 사용하고 super 사용
Player({
required this.team,
required String name
}) : super(name: name);
// Human의 함수를 재정의하고 싶은 겨웅
@override
void sayHello() {
}
}
// super는 부모 클래에 접근할 수 있게 해준다.
void main() {
var player = Player(team: Team.red, name: 'neander');
player.team = Team.red
}
Mixin class, 생성자가 없는 클래스
: Mixin class의 조건은 클래스 내부에 생성자가 없어야 한다.
: Mixin class역할은 해당 클래스의 설정 값을 사용하는 것,
: 사용할 클래스에서 extends가 아닌 'with'를 사용
// 부모 클래스가 아닌 내부 내용을 뺏어오는 것이다.
// Mixin의 조건은 생성자가 없어야한다. **
class Strong {
final double strengthLevel = 1500.99;
}
class QuickRunner {
void runQuick() {
print("run!!!");
}
}
class Tall {
final double height = 1.99;
}
// 모든 클래스를 다 긇어온다.
class Player with Strong, QuickRUnner, Tall {
}
void main() {
var player = Player();
player.runQuick(); // 사용이 가능하다.
}
니콜라스(노마더 코드) 최고♥
'lan > dart' 카테고리의 다른 글
[Dart] Dart SDK 위치 (0) | 2023.12.13 |
---|---|
[Dart] StringBuffer : like java's StringBuilder (0) | 2023.12.08 |
[Dart] 3. 함수 사용(Function) (0) | 2023.12.05 |
[Dart] 2. Data Types (0) | 2023.12.05 |
[Dart] 1. Dart 언어시작 (0) | 2023.12.05 |