简体   繁体   中英

Dart named constructor, static method, and factory constructor

Given the following code:

const jsonString = '{"myString":"Hello"}';
final jsonMap = jsonDecode(jsonString);

final myObject = MyClass.fromJson(jsonMap);

How many ways are there to create a new object using this syntax:

MyClass.fromJson(jsonMap)

Recently I've been trying to understand the differences between named constructors, factory constructors and static methods so I'm posting my answer below so that I have something to come back to as a reference in the future.

To create a new instance of an object using the following syntax:

MyClass.fromJson(jsonMap)

For use with the following code:

// import 'dart:convert';

const jsonString = '{"myString":"Hello"}';
final jsonMap = jsonDecode(jsonString);

final myObject = MyClass.fromJson(jsonMap);

There are at least the following ways to do it (with supplemental notes about the characteristics of each):

Generative constructor

class MyClass {
  MyClass(this.myString);
  final String myString;

  MyClass.fromJson(Map<String, dynamic> json) : this(json['myString']);
}

There are two kinds of generative constructors: named and unnamed. The MyClass.fromJson() is a named constructor while MyClass() is an unnamed constructor. The following principles apply to generative constructors:

  • Generative constructors may only instantiate the class itself.
  • Generative constructors can use an initializer list.
  • Generative constructors may only use initializing parameters or the initializer list to set final properties, that is, not in the constructor body.
  • Generative constructors can be const , even if they are not redirecting.

Factory constructor

class MyClass {
  MyClass(this.myString);
  final String myString;

  factory MyClass.fromJson(Map<String, dynamic> json) {
    return MyClass(json['myString']);
  }
}
  • Factory constructors may return a subtype of the class.
  • Factory constructors can be used to create singletons.
  • Factory constructors can be unnamed like generative constructors.
  • Factory constructors can be const , but only when redirecting.

Static method

class MyClass {
  MyClass(this.myString);
  final String myString;

  static MyClass fromJson(Map<String, dynamic> json) {
    return MyClass(json['myString']);
  }
}
  • Static methods may return anything, including a Future.
  • Static methods can be used to create singletons.
  • Static methods can be used as tear-offs.

Further reading

In addition to @suragch detailed answer. I like to give some bullet points that show factory constructor is the best option for the above scenario (for fromJson() method).

  • When using factory constructors, you don't need to initialize instance variables of that class. (but when you using generative constructors, need to initialize all the final instance variables)

  • Factory constructor can return an existing object. Eg:- when using json_seriazible package, fromJson() method return an existing (previously made) object. So we can only use factory constructors with this package.

  • Factory constructors can return any subtype of that class, but when using generative constructors, it can only return the exact type object of that class.

  • Ensures only one instance of a class is ever created (singleton pattern). (object are expensive, so singleton pattern should needed for fromJson)

According to the above points, we can see generative constructors add more limitations for fromJson constructor and static methods give fewer limitations for fromJson so it can cause type errors by returning different type objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM