Class
에서 사용되는 parameter(and argument) 그리고 Immutable Programing 정리
void main() {
Person person = Person("홍길동", 20);
person.sayHello();
}
class Person {
String name;
int age;
Person(String name, int age)
: this.name = name,
this.age = age;
// 약식 표현. Flutter, Dart에서는 약식 표현을 권장한다.
// Person(this.name, this.age);
void sayHello() {
print("Hello my name is $name , I'm $age years old");
}
}
여기서 사용된 :
(콜론)은 클래스를 초기화 하겠다고 선언하는 것.
즉, name과 age 변수를 초기화한다.
파라미터를 중괄호({}
)로 감싸면 named parameter가 되어 이름으로 파라미터를 전달할 수 있다.
named parameter를 사용하기 위해서는
parameter는 중괄호({}
)를 사용하며 required
(필수)을 인자 앞에 배치한다.
`@required` 는 필수로 입력해야 하는 값이면 입력하지 않으면 컴파일 되지 않는다.
`{}`와 `@required` 는 독립적인 존재이다.
argument는 인자: 값
으로 호출한다.
void main() {
Person person = Person(name: "홍길동", age: 20);
person.sayHello();
}
class Person {
String name;
int age;
// named constructor parameter
Person({required String name, required int age})
: this.name = name,
this.age = age;
// named constructor parameter 약식 표현, Dart에서는 약식 표현을 권장한다.
// Person({required this.name, required this.age});
void sayHello() {
print("Hello my name is $name , I'm $age years old");
}
}
파라미터를 대괄호([]
)로 감싸면 선택형 인자를 설정할 수 있다.
선택사항이기 때문에 이름 없이 호출할 수도 있다.
void main() {
Person hong = Person("홍길동");
hong.sayHello();
// 나이는 비밀.
Person naruto = Person("나루토", 20);
naruto.sayHello();
// 제 나이는 20.
}
class Person {
String name;
int? age;
Person(String name, [int? age])
: this.name = name,
this.age = age;
// 약식 표현. Flutter, Dart에서는 약식 표현을 권장한다.
// Person(this.name, [this.age]);
void sayHello() {
// print("Hello my name is $name ,I'm $age years old.");
age is int ? print("제 나이는 $age.") : print("나이는 비밀.");
}
}
?
를 붙인다.[this.인자]
로 감싼다.parameter의 기본값을 설정할 수 있다.
void main() {
Person hong = Person("홍길동");
hong.sayHello();
// Hello my name is 홍길동 ,I'm 30 years old.
Person naruto = Person("나루토", 20);
naruto.sayHello();
// Hello my name is 나루토 ,I'm 20 years old.
}
class Person {
String name;
int? age;
Person(String name, [int? age = 30])
: this.name = name,
this.age = age;
// 약식 표현. Flutter, Dart에서는 약식 표현을 권장한다.
// Person(this.name, [this.age = 30]);
void sayHello() {
print("Hello my name is $name ,I'm $age years old.");
}
}
?
를 붙인다.[this.인자 = 값]
로 감싼다.이름이 있는 생성자이며 여러 생성자를 만들 수 있다는 특징이 있다.
named, optional 파라미터를 사용해서 만들 수 있다.
list나 map등으로 받을때도 사용된다.
void main() {
var tracer = Player(name: "트레이서", age: 26, team: 'blue', power: 2);
var tracerBlueBot = Player.createBluePlayer(name: "트레이서_봇", age: 26);
var tracerRedBot = Player.createRedPlayer("트레이서_봇", 26);
tracer.sayHello(); // 트레이서. 나이 : 26. blue팀
tracerBlueBot.sayHello(); // 트레이서_봇. 나이 : 26. blue팀
tracerRedBot.sayHello(); // 트레이서_봇. 나이 : 26. red팀
}
class Player {
String name, team;
int age, power;
// class를 호출할 때 마다 기본으로 호출되는 기본 constructor
// named constructor parameter
Player({
required this.name,
required this.age,
required this.team,
required this.power,
});
// 1. Named constructor
// Named Parameters 방식
Player.createBluePlayer({
required String name,
required int age,
}) : this.name = name,
this.age = age,
this.team = 'blue',
this.power = 1;
// 2. Named constructor
// Positional Parameters 방식
Player.createRedPlayer(String name, int age)
: this.name = name,
this.age = age,
this.team = 'red',
this.power = 1;
void sayHello() {
print("${name}. 나이 : ${age}. ${team}팀");
}
}
List<Map>
으로 감싸진 json 형태를 객체화 시키는 예제
void main() {
// 3. 객체를 담을 리스트 작성
List<ToonModel> toonInstances = [];
// 1. 객체화 하려는 데이터
List<Map<String, dynamic>> toonList = [
{'title': '진격의거인', 'thumb': 'img1.jpg', 'id': 1021},
{'title': '귀멸의칼날', 'thumb': 'img2.jpg', 'id': 2503},
{'title': '나루토', 'thumb': 'img3.jpg', 'id': 6234},
];
// 4. 객체를 리스트에 넣어준다.
for (var toon in toonList) {
final toonInfo = ToonModel.fromJson(toon);
toonInstances.add(toonInfo);
}
// 5. 객체출력
for (int i = 0; i < toonInstances.length; i++) {
print(
"제목 : ${toonInstances[i].title}, 이미지 : ${toonInstances[i].thumb}, 아이디 : ${toonInstances[i].id}");
}
/*
제목 : 진격의거인, 이미지 : img1.jpg, 아이디 : 1021
제목 : 귀멸의칼날, 이미지 : img2.jpg, 아이디 : 2503
제목 : 나루토, 이미지 : img3.jpg, 아이디 : 6234
*/
}
// 2. 객체화를 위한 틀 만들기
class ToonModel {
String title, thumb;
int id;
ToonModel.fromJson(Map<String, dynamic> json)
: title = json['title'],
thumb = json['thumb'],
id = json['id'];
}
Named Constructor는 Flutter에서 흔하게 사용되는 패턴이다.
Immutable이란 불변성을 뜻하며, Immutable 객체는 객체가 가지고 있는 값을 변경할 수 없는 객체를 의미한다. 즉, 값이 변경될 수 없게 방지한다.
값을 변경하고 싶으면 새로운 객체를 생성하고 변경된 값을 주입해야 한다.
void main() {
Person person = Person("홍길동", 20);
person.sayHello();
// immutable이 적용되어 객체의 값 변경불가.
// person.age = 10;
}
class Person {
// final 선언
final String name;
final int age;
// const 선언
const Person(String name, int age)
: name = name,
age = age;
void sayHello() {
print("Hello my name is $name , I'm $age years old");
}
}
Immutable 을 사용하려면
const
를 붙인다.final
을 붙인다.
const
와final
은 모두 불변하는 상수를 의미하며 차이가 있다.
const
는 compile-time constant로 앱 빌드시 값이 정해진다.
final
은 run-time constant로 앱 빌드시에는 값이 정해지지 않지만 앱 실행시 값이 정해진다. (DataTime.now, Device size 등)
모든 위젯을 만들때 StatelessWidget 혹은 StatefulWidget 을 상속받아 위젯을 만들곤 한다. 이 둘은 Widget이라는 객체를 상속받고 있다. Widget은 스스로 변경가능한 상태 값을 갖고 있지 않도록 설계되어 있다.
Flutter의 모든 위젯들은 immutable로 설계되어 있으며, StatefulWidget 마저 immutable 한 클래스이다.(새로운 값을 가질 수 있는 이유는 StatefulWidget 생성시 State<Class>
를 extends
하는 두번째 클래스 때문이다. 두번째 클래스가 mutable 하도록 설계 된듯 하다.)
main.dart
List<String> images = [
"assets/feed_01.jpeg",
"assets/feed_02.jpeg",
"assets/feed_03.jpeg",
];
ListView.builder(
itemCount: images.length,
itemBuilder: (context, index) {
final image = images[index];
return Feed(
imageUrl: image,
);
},
)
feed.dart
class Feed extends StatefulWidget {
const Feed({
Key? key,
required this.imageUrl,
}) : super(key: key);
final String imageUrl;
State<Feed> createState() => _FeedState();
}
class _FeedState extends State<Feed> {
}
예제와 같이 Feed 클래스를 객체화 하기 위해 constructor 앞에 const로 선언하며 변수도 final로 선언한다.
immuable의 반대는 mutable이다.
reference