Skip to content

Latest commit

 

History

History
115 lines (98 loc) · 4.04 KB

특이한 형태의 3가지 생성자.md

File metadata and controls

115 lines (98 loc) · 4.04 KB

특이한 형태의 3가지 생성자

1. Constructor List를 활용한 생성

class DateManager {
  int date;
  String weekday;
  int month;
  int year;

  DateManager({
    required this.date,
    required this.weekday,
    required this.month
    // required this.year
  }) : year = DateTime.now().year;
}
  • (:) 콜론 뒷 구절은 생성자 본문이 실행되기 전에 변수를 초기화한다는 뜻임
  • 만약, 두 시점 모두 초기화구문을 설정해버리면 아래 오류가 발생한다.

Error: 'year' was already initialized by this constructor.

  • why? 초기화리스트는 초기화 본문보다 먼저 값을 설정해버리므로 이미 year에는 값이 들어와있는 상태라는거다.
  • 그니까 두번 값을 할당하는 쓸데없는 짓 하지마라는거죠
  • 또한, private으로 설정된 속성을 초기화 할 때도 생성자목록을 통해 초기화 해주어야한다.
class DateManager {
  int date;
  String weekday;
  int month;
  int year;

  DateManager({
    required this.date,
    required this.weekday,
    required this.month
    this.year = DateTime.now().year;
  });
}
//- Error: Cannot invoke a non-'const' constructor where a const expression is expected.Try using a constructor or factory that is 'const'.
  • 위 구문은 왜동작하지 않을까?
  • Constructor에는 선언 시 상수가 들어가야함.
  • 하지만 DateTime.now().year는 상수가 아닌 값이므로 에러가 발생하는 것
  • 즉, 상수가 아닌 값을 초기화 시 할당할 때 이니셜라이저 목록은 유용 할 수 있다.

2. Named Constructors

// Top-Level
const double xOrigin = 3.0;
const double yOrigin = 1.0;

class Point {
  final double x;
  final double y;

  // formal constructor
  Point(this.x, this.y);

  // Named constructor
  Point.origin()
      : x = xOrigin,
        y = yOrigin;

  Point.estimate()
      : x = xOrigin - 12.5,
        y = yOrigin - 13.5;
}

final originPoint = Point.origin();
print(originPoint.x); // 3.0

final estimatedPoint = Point.estimate();
print(estimatedPoint.x); // -9.5
  • dart에서는 기본적으로 생성함수의 오버로드가 지원되지않음.
  • 지원하지않는 이유는 Named parameter로 어느정도 커버가 가능하기에..
  • 하지만, 아래의 명명된 생성자로도 (오버로드)는 아니지만 유사하게 커버가능하다.
  • 결론은 Named Constructor를 활용해서 여러 생성자를 구현 가능하다.
  • 하지만, 이는 코드의 가독성을 저해할 여지가있다. (why? 한눈에 봐서는 정적 메서드와 구분이 힘들 수 있기에..)
  • 따라서, 사용은 꼭 필요한게 아니면 지양하는 것으로 하자.

3. factory Constructors

@JsonSerializable
class Human {
  final String gender;
  final String age;
  final String name;

  Human({
    required this.gender,
    required this.age,
    required this.name
  });

  // Map에서 새로운 Human 인스턴스를 생성하기 위해 필요한 팩토리 생성자입니다.
  // build runner를 통해 생성된 _$HumanFromJson() 생성자에게 Map을 전달합니다.
  factory Human.fromJson(Map<String, dynamic> json) $HumanFromJson(json);

  // toJson은 클래스가 JSON 인코딩의 지원을 선언하는 규칙입니다.
  Map<String, dynamic> toJson() => _$HumanToJson(this);
}

Factory Constructors 정리글 위 블로그엔 이런 클래스가 있더라... 무슨소리인지 모르겠지만 하나하나 알아가보자.

  • factory 키워드는 flutter에서 모델 클래스를 만들 때 자주 사용되는 예약어임.
  • dart 공식문서에는 아래와 같이 정의되어있다.

클래스의 새로운 인스턴스를 항상 생성하지 않는 생성자를 구현할 때 factory 키워드 사용

  • 몬솔???
  • 하나의 클래스에서 하나의 인스턴스만 생성한다.
  • factory constructors에서는 this에 접근이 불가능하다.
  • 사용하면 기존의 인스턴스를 반환받아 사용한다?
  • 이거 이해가 가지않는다... 한번 물어보고 더 정리해보자