1. 생성자 이해
class Person {
int id;
String name;
late int money; // 나중에 들어옴 or 디폴트 = 0; >> late = null을 허용하지만 반드시 값이 들어와야함.
String? nickname; // 있을수도 있고 없을수도 있다.
Person(this.id, this.name, this.money, this.nickname);
}
void main() {
Person p = Person(1, "홍길동", 1000, "hong");
}
class Person {
int id;
String name;
late int money;
String? nickname;
Person(this.id, this.name, this.money, this.nickname); // 이름이 없는 생성자
// 여러 버전의 생성자 만들기 >> 이니셜 라이져 (:) >> 이름이 있는 생성자 생성시 사용
Person.formMap(Map<String, dynamic> m)
: this.id = m["id"],
this.name = m["name"],
this.money = m["money"], // 생성자에서 연산이 필요한경우
this.nickname = m["nickname"] ?? "null이면 들어오는 기본 값";
void init() { // 함수를 하나 만들어서
if (money == 0) {
for (int i = 0; i < 10; i++) {
money = money + 1;
}
}
}
}
void main() {
var m = {"id":1, "name":"홍길동", "money":0};
Person p2 = Person.formMap(m)..init(); // 생성할 때 함수를 이어붙임 >> (..함수): cascade 연산자
print(p2.id);
print(p2.name);
print(p2.money);
print(p2.nickname);
}
2. Mixin
mixin class Engine {
int power = 100; // 'Engine' 클래스의 필드로 기본값 100을 설정
}
class Car with Engine {
// 'Car' 클래스가 'Engine' 믹스인을 포함 (with 키워드를 사용)
// 'Engine'의 모든 필드와 메서드를 'Car' 클래스가 상속받은 것처럼 사용 가능 >> 다중 상속 가능
}
void main() {
Car c = Car(); // 'Car' 객체 생성
print(c.power); // 'Car'가 'Engine'의 필드인 'power'를 상속받아 사용 가능
}
3. final, const
// 1. 'primaryColor'는 컴파일 타임에 초기화되는 상수 >> 메인 실행 안 해도 초기화 >> 주로 사용됨
const primaryColor = "green";
// 2. 'secondaryColor'는 런타임에 초기화되는 상수 >> 메인 실행시 초기화
final secondaryColor = "red";
class Button {
final String text; // 'text'는 변경 불가능한 final 변수 (런타임에 초기화됨)
// 3. 'Button' 클래스의 생성자는 'const'로 선언되어 있어, 컴파일 타임에 객체를 생성할 수 있음
const Button(this.text); // 'const' 생성자를 사용하여 'Button' 객체가 상수로 만들어짐
}
void main() {
// 4. 'const' 생성자를 사용해 상수 객체를 생성
Button b1 = const Button("로그인"); // 'b1'은 컴파일 타임에 초기화된 상수 객체
// 5. 'const' 생성자를 사용해 동일한 값으로 또 다른 상수 객체 생성
Button b2 = const Button("로그인"); // 'b2'도 컴파일 타임에 초기화된 상수 객체
// 6. 'const'가 아닌 일반 객체 생성
Button b3 = Button("로그인"); // 'b3'은 런타임에 초기화된 객체
// 7. 각 객체의 해시코드를 출력하여, 동일한 객체가 생성되었는지 확인
print(b1.hashCode);
print(b2.hashCode);
print(b3.hashCode);
}
4. collection
- List와 Map
var list = [1, 2, 3, "ds"];
// Dart에서 var는 타입을 자동 추론함
// 이 리스트는 여러 타입의 요소를 포함할 수 있는 List<dynamic> 타입으로 선언됨
// List<int> list2 = [1, 2, 3, "ds"];
// 위 코드는 컴파일 에러 발생: List<int>는 정수(int)만 허용하지만 "ds"는 문자열(String)
var map = {
"id": 1, // 키 "id"와 값 1 (정수형)
"name": "홍길동" // 키 "name"과 값 "홍길동" (문자열)
};
// map의 타입은 Map<String, dynamic>으로 추론됨 (key는 String, value는 다양한 타입 가능)
void main() {
// 1. 리스트 요소 접근
print(list[1]); // 리스트의 1번 인덱스 값 출력 (결과: 2)
// 2. 맵 값 접근
print(map["name"]); // 키 "name"에 해당하는 값 출력 (결과: 홍길동)
// 3. 리스트에 요소 추가
list.add(4); // 리스트에 값 4 추가
print(list); // 리스트 출력 (결과: [1, 2, 3, "ds", 4])
print("-----");
// 4. 맵에 새로운 키-값 쌍 추가
map["phone"] = "010-1234-5678"; // 키 "phone"과 값 추가
print(map); // 맵 출력 (결과: {"id": 1, "name": "홍길동", "phone": "010-1234-5678"})
}
- List 컨트롤
var list = [1, 2, 3];
// 기본 리스트 선언
void main() {
// 1. 깊은 복사
var r1 = [...list];
// ... 전개연산자를 사용해 'list'의 모든 요소를 새로운 리스트에 복사 (깊은 복사)
// 2. 추가
var r2 = [...list, 4];
// 기존 'list'의 요소를 전개하고, 끝에 4 추가
// 3. 삭제
var r3 = [...list].where((element) => element != 2).toList();
// 리스트에서 요소가 2가 아닌 것만 필터링하여 새로운 리스트 생성
print(r3); // 결과: [1, 3]
// 4. 검색
var r4 = list.where((element) => element == 2).toList();
// 리스트에서 요소가 2인 것만 필터링하여 새로운 리스트 생성
print(r4); // 결과: [2]
// 5. 수정
var r5 = list.map((element) => element == 2 ? 5 : element).toList();
// 리스트의 모든 요소를 순회하며 2인 요소는 5로 변경, 나머지는 그대로 유지하여 새로운 리스트 생성
print(r5); // 결과: [1, 5, 3]
}
Share article