A Quick Introduction To Different Dart Constructors

Flutter category image
Reading Time: 4 minutes

Default, named, constant, factory?!? Here is a quick introduction to different Dart constructors.

Everybody needs to use constructors. And everybody needs to know what’s possible with them. So here is a quick introduction to different Dart constructors.

Default Constructor

The default constructor is the constructor type you probably use the most. It creates an instance of an object and is essential in any object-oriented programming language. Here is a small code example:

Dart
class MyClass {
	MyClass() {
		print("default constructor");
	}
}

// call example
final myObject = MyClass();

While many other programming languages require a keyword like new, Dart got rid of that since v2.0.

Named Constructor

Named constructors are perfect to create objects for specific purposes or give developers the ability to create objects in multiple ways. Have a look at the DateTime class of Dart. It has a default constructor and 5 named constructors (fromMicrosecondsSinceEpoch, fromMillisecondsSinceEpoch, now, timestamp, utc).

The developers have the freedom to use whatever constructor matches their preferred style and available data. Here is a code example for named constructors:

Dart
class MyClass {
	MyClass.anotherConstructor() {
		print("named constructor");
	}
}

// call example
final myObject = MyClass.anotherConstructor();

You don’t need to define a default constructor because if you omit it, it is created automatically.

Constant Constructor

A class that only contains unchangeable values (const and final), can declare a const constructor. The Dart compiler can optimize this code and make your app faster. Have a look at this example below:

Dart
class MyClass {
	final int id;
	
	const MyClass(this.id);
}

// call example
final myObject = const MyClass(5);

Consider using this constructor type as often as possible to speed up your final product! It is also possible to combine the const keyword with named constructors.

💡 Tip

A constant constructor cannot have a body!

Private Constructor

A private constructor is not publicly accessible but only from within the class itself or the Dart file it is defined in. Usually you will have other types of constructors that expose it to the public. Let’s have a look at the code:

Dart
class MyClass {
	MyClass._() {
		print("private constructor");
	}
}

// call example
// Only works when called from within the same file!
final myObject = MyClass._();

You can also name your private constructor as long as it starts with an underscore.

Get Free Daily Flutter Content!

Small daily Flutter portions delivered right in your inbox. A title, an abstract, a link, and you decide if you want to dive in!

Factory Constructor

A factory constructor is useful when you don’t always create a new object. The Singleton pattern is the perfect example for this type of constructor. Here is the code:

Dart
class MyClass {
	static MyClass _instance;
	
	MyClass._();
	
	factory MyClass() {
		print("factory constructor");
		if (_instance == null) {
      _instance = MyClass._();
    }
    return _instance;
	}
}

// call example
final myObject = MyClass();
final myNewObject = MyClass();

print(myObject == myNewObject) // returns true

You can also combine the factory keyword and a named constructor.

💡 Tip

Factory constructors can’t access the this context.

Redirecting Constructor

A redirecting constructor redirects the call flow to another constructor. This can be any constructor type except factory constructors. You can also chain redirecting calls as much as you want. Here is a quick example of a named constructor that redirects to the default constructor:

Dart
class MyClass {
  String name;
  int age;
  
	MyClass(this.name, this.age);
	
	MyClass.example() : this("Rahul", 35)
}

// call example
final myObject = MyClass.example();

Use the this context to access other constructors and instance fields in a redirecting constructor.

💡 Tip

A redirecting constructor cannot have a body!

Super Constructor

A super constructor looks similar to a redirecting constructor but it calls constructors in the base class. All other possibilites of redirecting constructors are also available here like chaining calls or passing arguments. Again some code:

Dart
class MyClass {
  String name;
  int age;
  
	MyClass(this.name, this.age);
}

class AnotherClass extends MyClass {
	String country;
	
	AnotherClass(super.name, super.age, this.country);
	// or
	AnotherClass(String name, int age, this.country) : super(name, age);
}

// call example
final myObject = AnotherClass("Rahul", 35, "India");

While a redirecting constructor can’t have a method body, a super constructor can! And there are currently two synatic options to call a super constructor with arguments. Both lead to the same result.

Remarks

From other programming languages, you might know constructor overloading. This means defining multiple constructors with the same name but different parameters. Here is an example with C#:

C#
class Person {
  public string Name { get; set; }
  public int Age { get; set; }
  
  // Default constructor
  public Person() {
    Name = "Unknown";
    Age = 0;
  }
  
  // Constructor with one parameter
  public Person(string name) {
    Name = name;
    Age = 0;
  }
  
  // Constructor with two parameters
  public Person(string name, int age) {
    Name = name;
    Age = age;
  }
}

This is not possible with Dart. But you can shift around that problem by defining multiple named constructors and redirecting them to the default constructor, for example. Here is what I mean:

Dart
class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
  
  Person.empty() : this("Unknown", 0);
  
  Person.nameOnly(String myName) : this(myName, 0);
  
  Person.ageOnly(int myAge) : this("Unknown", myAge);
      
  Person.nameAndAge(String myName, int myAge) : this(myName, myAge);
}

Conclusion

In this article, I gave you a quick introduction to different Dart constructor types. With this guide you should know the differences and when to use what, no matter if you need default, named, const, factory, or super constructors.

Related articles


Leave a Reply

Your email address will not be published. Required fields are marked *