var type

- 어떤 타입의 변수든 선언이 가능하다.

- 하지만 한번 선언하고 나면 해당 타입으로 고정된다.

- 때문에 선언 후에 다른 타입으로 대체하여 사용 불가능하다.

- 참고 : 선언 시 값을 지정하지 않아 type인식이 되지 않으면 dynamic type처럼 타입변경이 가능하다.

 

dynamic type

- var type과 다르게 한번 변수의 타입이 지정되어도 다른 변수타입으로 바꿀 수 있다.

- 협업의 관점에서, 타인이 코드를 봤을 때 명료한 이해를 어렵게 만드므로 사용을 권장하지 않는다. 

 

- String 첫 스펠링을 대문자로 시작한다.

- print함수 사용시 $변수이름 으로 할당이 가능하다.

void main(){
  String lname = 'hong';
  String fname = 'gildong';
  print('$fname ${lname}');
}

출력 : gildong hong

 

 

람다식과 익명함수

void main(){
  routine((){ // 익명함수 -> 함수의 이름이 없음. 바로 함수를 넣어준다.
    return "짜파게티 먹기";
  });
  
  routine(()=>"삼양라면 먹기"); // 람다식은 무조건 리턴
}

void routine(Function start){
  String result = start();
  print(result);
}

/*
간결하게 사용할때는 람다식을 쓴다.
간단히 호출시? 사용한다.
*/

 

 

선택적 매개변수

//선택적 매개변수
class Dog {
  String name;
  int age;
  String color;
  int thirty;
  //인스턴스 함수의 매개변수들을 중괄호로 묶으면 선택전 매개변수화 시킬 수 있다.
  Dog({this.name, this.age, this.color, this.thirty});
}

void main(){
  // 순서상관이 없어지고 모든 변수를 할당할 필요가 없어진다.
  Dog d1 = Dog(name: "Toto", age: 13, color: "white", thirty: 100);
  Dog d2 = Dog(name: "Mimi", thirty: 50);
}

 

cascade 연산자 (계단표기법) ..

class Chef {
  
  void cook(){
    print("start cooking");
  }
  
  void handWash(){
    print("wash a hand");
  }
}

// 이 함수는 수정불가능 하다고 가정
void goCompany(Chef c){
  c.cook();
}

void main(){
  // 객채를 넘지면서 함수를 실행할 수 있다.
  goCompany(Chef()..handWash()..cook());
}

 

상속과 initializer keyword

class Burgur {
  String name;
  Burgur(this.name){
    print(name);
  }
}

class CheeseBurgur extends Burgur{
  //initializer keyword - ": super(name)"
  // CheeseBurgur()의 내부가 실행되기 전에 버거가 실행된다. 따라서 Burgur()에서 name을 찍으면 null 이 나온다.
  // 하지만 이니셜라이져 키워드를 이용하여 super에게 name을 넘겨줄 수 있다. 
  // 그러면 Burgur실행히 name이 초기화가 되어지기 때문에 "치즈햄버거"가 출력된다.
  // 즉 부모가 생성될때 값을 넘기기위해 이니셜라이져 키워드를 사용한다.
  CheeseBurgur(String name) : super(name){
    super.name = name;
  }
}

void main(){
  Burgur cb = CheeseBurgur("치즈햄버거");
}

 

mixin

class Engine {
  int power = 5000;
}

// 믹스인 : 코드재사용을 위해 사용한다.
class BMW with Engine{
  
}
  
  
void main(){
  BMW bm = BMW();
  print(bm.power);
  // 출력 : 5000
}

 

추상클래스 abstract class

abstract class Animal { // 추상클래스, abstract class
  void sound();
}

class Dog implements Animal{
  void sound(){
    print("멍멍 배고파");
  }
}

class Cat implements Animal{
  void sound(){
    print("야옹 배고파");
  }
}

class Fish implements Animal{
  @override // --> 부모의 함수를 무효화시킨다.
  void sound() {
    print("뻐끔뻐끔 배고파"); // --> 재정의한다.
  }
  
  
}

void main(){
  Dog d1 = Dog();
  Cat c1 = Cat();
  Fish f1 = Fish();
  
  d1.sound();
  c1.sound();
  f1.sound();
  //멍멍 배고파
  //야옹 배고파
  //뻐끔뻐끔 배고파
}

List, Map(collection)

//컬랙션 (수집된 물품들)

// int,double, String, bool
// 이들은 커스텀 자료형

class User {
  int id=1;
  String username="cos";
}

void main(){
 // List
  List<int> nums = [1,2,3,4];
  print(nums); // [1, 2, 3, 4]
  
  var nums2 = [3,4,5];
  print(nums2); // [3, 4, 5]
 
 //Map
  Map<String, dynamic> user = {
    "id":1,
    "username":"cos"
  };
  
  print(user["id"]); // 1
  print(user["username"]); // cos
  User u1 = User(); // class 와도 비슷함
  User u2 = User();
}

 

단축키

control + / : 주석 해제 및 주석 설정

alt+enter : override method 작성

 

 

map, where (data를 다룰때 중요함)

void main(){
  var c =["새우초밥", "광어초밥", "연어초밥"];
  
  //map
  var cChange = c.map((i)=> "간장_"+i).toList();
  // map 은 반복되는 리스트를 변형해서 리턴해준다.
  // 괄호안에 있는 i 가 각 리스트의 변수들이다.
  // map 은 interable 타입으로 리턴해주기때문에 다시 리스트로
  // 변환시켜주기 위해 .toList()를 해준다.
  print(cChange);
  //[간장_새우초밥, 간장_광어초밥, 간장_연어초밥]
  
  
  //where
  var cFind = c.where((i)=> i=="광어초밥").toList();
  print(cFind);
  //[광어초밥]
  
  cFind = c.where((i)=> i!="광어초밥").toList();
  print(cFind);
  //[새우초밥, 연어초밥] // 광어초밥이 아닌 것만 배열에 담긴다.
  // --> 배열에서 특정 원소를 삭제할 떄 자주 쓰인다.
}

 

스프레트 연산자

 

//스프레드 연산자 엄청나게 중요함
// 깊은 복사, 데이터추가 및 수정
// 활용도가 높은 코드이다.
void main() {
  var list = [1,2,3];
  //var newList = list; // 얕은복사 = 레버런스복사
  var newList = [...list]; // 깊은복사 = 값을 복사
  // 리스트가 그냥 정수일때는 스프레드를 사용하면 별도의 영향받지 않는 리스트 할당 가능
  print(list);
  print(newList);
  
  list[0] = 10;
  print(list);
  print(newList);
  //[1, 2, 3]
  //[1, 2, 3]
  //[10, 2, 3]
  //[1, 2, 3]
    ---------------------------------------------------------
  var list = [{"id":1}, {"id":2}];
  var sublist = list; // 얕은 복사 -> 레퍼런스복사, 같은 주소값, 영향받음
  var newList = list.map((i)=>{...i}).toList(); // 리스트가 오브젝트 형태일때는 스프레드를 사용해야 독립적인, 영향받지 않는 변수 생성가능
  print(list);
  print(newList);
  print(sublist);
  
  list[0]["id"] = 10;
  print(list);
  print(newList);
  print(sublist);
  
  print(list.hashCode);
  print(newList.hashCode);
  print(sublist.hashCode);

  //---------------------------------------------------------
  var users = [
    {"id":1, "username":"cos", "password":1234},
    {"id":2, "username":"ssar", "password":5678},
  ];
  print(users);
  
  // 중요!! 값 변경하여 저장하기
  // ...i 뒤에 "username":"love"를 붙임으로써 덮어써버리는 것이다. => 스프레드 연산자를 이용하여 username만 수정 + 추가가 가능
  var newUsers = users.map((i)=>i["id"]==2 ? {...i, "username":"love", "username2":"love"} : i);
  print(newUsers);
  //[{id: 1, username: cos, password: 1234}, {id: 2, username: ssar, password: 5678}]
  //({id: 1, username: cos, password: 1234}, {id: 2, username: love, password: 5678, username2: love})

}

 

const, final 차이점

// const, final
// 공통점 : 값을 한번 설정하면 변경 불가
// 차이점
// final : 런타임시에 초기화되어야 한다. define시 값을 설정해줘야함.
// const : 컴파일시에 초기화되어야 한다.
class Dog{
  final name;
  const Dog(this.name);
}

void main(){
  final n1;
  const n2=2;
  n1 = 3;
  Dog a1 = const Dog("any");
  Dog a2 = const Dog("any");
  print(a1.hashCode);//928468236
  print(a2.hashCode);//928468236
// const : 동일한 객체는 메모리를 공유한다.
}

 

Null safety

//방법1
class Person{
  String? name;
  int? age;

  Person({this.name, this.age});
}

//방법2
class Person{
  String name;
  int age;

  Person({required this.name, required this.age});
}


void main(){
  Person p =Person(name: "홍길동", age: 19);
  print(p.name);
  print(p.age ?? 1);
}

/*
key값으로 접근하여  class를 생성하는 것이 직관적이고 보기 편하다.
-> 그러러면 선택적 매게변수를 써야 한다.
-> 이때 null값이 발생할 가능성이 있다.
-> null Sagefy로 인해 오류가 발생할 수 있다. 
-> null 이 발생하지 않도록 안전하게 코딩하기 위해 도입되었다.
방법1
-> 때문에 String? 처럼 null 타입을 포함하도록 설정해야 한다. 
방법2
-> 선택적 매게변수를 받을때 required 를 써서 무조건 넣도록 한다.
*/

+ Recent posts