이번 포스팅은 저번 포스팅에 이어서 class에 대한 포스팅을 진행하도록 하겠습니다.
저번 포스팅에서 class는 특징들을 프로퍼티로 생성할 수 있다고 했습니다. 하지만 main메소드 안에서 class변수를 선언할 때, 각 프로퍼티에 값을 전달해야 했었죠?? 무조건이 아닙니다. 프로퍼티에 값을 전달하지 않아도 선언할 수 있게 하는 방법이 있습니다. 바로 nullable인데요. 밑에 예시로 알아보겠습니다.
지난 포스팅에서 등장한 사람들은 애완동물을 키울수도, 안키울수도 있겠죠? 그렇다면 프로퍼티에 애완동물의 이름, petName이라는 프로퍼티를 선언해보겠습니다. 애완동물을 기르지 않는다면 이름을 전달할 수 없겠군요?
void main() {
var A = Human('철수', 20, 'student', 'korea');
var B = Human('민수', 23, 'teacher', 'korea');
}
class Human {
final String name;
int age;
String _job;
String country;
String? petName;
Human(this.name, this.age, this._job, this.country, [this.petName]);
void introduce() {
print("이름은 $name이고, 나이는 $age이며, 직업은 $_job입니다.");
}
}
이처럼 nullable을 이용해서 프로퍼티를 선언한 후, 초기화를 위해서 대괄호를 씌우면 됩니다.
A와 B는 나이를 기준으로 20살 이상이면 성인이라고 할 수 있겠습니다. 그렇다면, isAdult라는 불리언 프로퍼티를 생성해서 나이에 의해서 결정할 수 있군요. 이처럼 다른 프로퍼티에 의해서 나중에 초기화를 해야할 경우, late를 맨 앞에 붙여서 늦은 초기화를 시킬 수 있습니다.
void main() {
var A = Human('철수', 19, 'student', 'korea');
var B = Human('민수', 23, 'teacher', 'korea');
print(A.isAdult);
print(B.isAdult);
}
class Human {
String name;
int age;
final String _job;
String country;
String? petName;
late bool isAdult;
Human(this.name, this.age, this._job, this.country, [this.petName]) {
if (age >= 20) {
isAdult = true;
}
else {
isAdult = false;
}
}
void introduce() {
print("이름은 $name이고, 나이는 $age이며, 직업은 $_job입니다.");
}
}
>> false
>> true
지금까지 class를 생성하기 위해 전달된 값들은 모두 순서대로 프로퍼티에 전달됩니다. 하지만, 이런 순서와 무관하게 각 프로퍼티에 원할하게 전달해주고 싶을 땐, Constructor를 이용해서 class를 생성하면 됩니다.
void main() {
var A = Human(name: '철수', age: 19, job: 'student', country: 'korea');
}
class Human {
String name;
int age;
final String job;
String country;
String? petName;
late bool isAdult;
Human(
{required this.name,
required this.age,
required this.job,
required this.country,
this.petName}) {
if (age >= 20) {
isAdult = true;
} else {
isAdult = false;
}
}
void introduce() {
print("이름은 $name이고, 나이는 $age이며, 직업은 $job입니다.");
}
}
이렇게 선언해준다면, 프로퍼티에 값을 헷갈리지 않고 전달할 수 있습니다.
자 이번엔 Named Constructor에 대해서 알아볼겁니다. 그 전에 우리가 예시로 들었던 class는 갈아버리고, 정말 교육용으로 보이는 class로 선언해보겠습니다.
void main() {
var a = A(10, 20)
print(a.x);
}
class A {
int x = 0;
int y = 0;
A(this.x, this.y);
}
>> 10
A라는 class는 x, y를 프로퍼티로 두고 있습니다. 여기서 A를 Named Constructor로 선언해보겠습니다.
void main() {
A a = A.fromMap({'x': 10, 'y': 20});
print(a.x);
}
class A {
int x = 0;
int y = 0;
A.fromMap(Map map) {
x = map['x'];
y = map['y'];
}
}
>> 10
둘은 동일한 class지만, 선언하는 방식에서 살짝 차이를 느낄 수 있습니다. Named Constructor는 말 그대로 이름으로 인스턴스를 생성할 수 있게 해줍니다.