본문 바로가기
Frontend, Client/Flutter

[Flutter] 플러터 - 다트 : 다양한 생성자 알아보기

by ggyongi 2022. 12. 9.
반응형

생성자를 통한 파라미터 초기화

class Point {
  final double x;
  final double y;
  
  Point(this.x, this.y);
}


네임드 생성자

const double xOrigin = 0;
const double yOrigin = 0;

class Point {
  final double x;
  final double y;

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


상속 관계에서 생성자 활용

class Vector2d {
  final double x;
  final double y;

  Vector2d(this.x, this.y);
}

class Vector3d extends Vector2d {
  final double z;

  // Forward the x and y parameters to the default super constructor like:
  // Vector3d(final double x, final double y, this.z) : super(x, y);
  Vector3d(super.x, super.y, this.z);
}


상속 관계에서 생성자 활용 - named 파라미터의 경우

class Vector2d {
  final double x;
  final double y;

  Vector2d({required this.x, required this.y});
}

class Vector3d extends Vector2d {
  final double z;

  // Forward the y parameter to the named super constructor like:
  // Vector3d.yzPlane({required double y, required this.z})
  //       : super.named(x: 0, y: y);
  Vector3d.yzPlane({required super.y, required this.z}) : super(x: 0);
}


Initializer list
body실행 전에 인스턴스 변수를 초기화할 수 있음

// Initializer list sets instance variables before
// the constructor body runs.
Point.fromJson(Map<String, double> json)
    : x = json['x']!,
      y = json['y']! {
  print('In Point.fromJson(): ($x, $y)');
}

아래와 같이 initializer list에서 슈퍼클래스 생성자를 호출할 때에는 슈퍼클래스 생성자를 가장 마지막에 써줘야 컴파일 에러가 안난다.

class Vector2d {
  final double x;
  final double y;

  Vector2d({required this.x, required this.y});
}

class Vector3d extends Vector2d {
  final double z;

  Vector3d.yzPlane({required super.y}) : z = 1, super(x: 0);
}

initalizer list에 assert 명령도 추가할 수 있다.

import 'dart:math';

class Point {
  final double x;
  final double y;

  Point.withAssert(this.x, this.y) : assert(x >= 0) {
	  print('In Point.withAssert(): ($x, $y)');
	}
}

void main() {
  var p = Point.withAssert(-1, 2);
}

console

Uncaught Error: Assertion failed


리다이렉트 생성자
this를 사용하여 다른 생성자에게 위임할 수 있다.

class Point {
  double x, y;

  // The main constructor for this class.
  Point(this.x, this.y);

  // Delegates to the main constructor.
  Point.alongXAxis(double x) : this(x, 0);
}


Const constructor
생성되는 인스턴스가 앞으로 변하지 않을 경우, 생성자 앞에 const 키워드를 붙일 수 있다. 그러면 컴파일 시점의 constant instance가 생성된다.
*생성자 선언부에 const가 없거나 생성자 호출부에 const가 없으면 동일성 보장이 되지 않는다.

class Point {
  final double x;
  final double y;

  const Point(this.x, this.y);
}

void main() {
  assert(const Point(1, 2) == const Point(1, 2));
}


팩토리 생성자
아래 코드와 같이 생성자가 항상 새로운 인스턴스를 만들지 않을 때 팩토리 생성자가 고려될 수 있다.
또는 initializing list만으로 final 변수에 대한 초기화를 할 수 없는 상황에서 유용할 수 있다.
팩토리 패턴을 굉장히 쉽게 구현할 수 있도록 도와주는 생성자이다.

class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to
  // the _ in front of its name.
  static final Map<String, Logger> _cache = <String, Logger>{};

  factory Logger(String name) {
    return _cache.putIfAbsent(name, () => Logger._internal(name));
  }

  factory Logger.fromJson(Map<String, Object> json) {
    return Logger(json['name'].toString());
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

 

다트 언어 공식문서 : https://dart.dev/guides/language/language-tour

 

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글