Search code examples
dartconstructorstatic-methods

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.


Solution

  • 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