Constructors in Dart
Dart

Constructors in Dart

Hey everyone, welcome to our new article! Today, we’ll learn Constructors in Dart. Let’s get started!

Constructors

Constructors are methods that create, or construct, instances of a class. That is to say, constructors build new objects. Constructors have the same name as the class, and the implicit return type of the constructor method is also same the same type as the class itself.

Default constructor

As it stands, your User class doesn’t have an explicit constructor. In case like this, Dart provides a default constructor. In case like this, Dart provides a default constructor that takes no parameters and just returns an instance of the class. For example, defining a class like this:

Constructors in Dart

Is equivalent to writing it like this:

Constructors in Dart

Including the default Address() constructor is optional.

Sometimes you don’t want the default constructor, though.
You’d like to initialize the data in an object at the same time that you create the object. The next section shows how to do just that.

Custom constructors

If you want to pass parameters to the constructor to modify how you class builds an object, you can. It’s similar to how you wrote functions with parameters.

Like the default constructor above, the constructor name should be the same as the class name. This type of constructor is called as generative constructor because it directly generates an objects of the same type.

Long-form constructor

In Dart the convention is to put the constructor before the property variables. Add the following generative constructor method at the top of the class body:

Constructors in Dart

This is know as a long-form constructor. You’ll understand why it’s considered “long-form” when you see the short-form constructor later.

this is a new keyword. What does it do?

The keyword this is the constructor body allows you to disambiguate which variable you’re talking about. It means this object. So this.name refers the object property called name, while name (without this) refers to the constructor parameter. Using the same name for the constructor parameters as the class properties is called shadowing. So the constructor above takes the id and name parameters and uses this to initialize the properties of the object.

Constructors in Dart

Once the object has been created, you can access its properties and other methods just as you did before.
However, you can’t use the default constructor User(), anymore, since id and name are required positional parameters.

Short-form constructor

Dart also has a short-form constructor where you don’t provide a function body, but you instead list the properties you want to initialize, prefixed with the this keyword.
Arguments you send to the short form constructor are used to initialize the corresponding object properties.

Here is the long form constructor that you currently have:

Constructors in Dart

Now replace that with the following short-form constructor:

Constructors in Dart

Dart infers the constructor parameter types of int and String from the properties themselves that are declared in the class body.

Run the code again. You’ll see the short-form constructor works just like the longer form you replaces, but it’s just a little tidier now.

Named constructors

Dart also has a second type of generative constructor called a named constructor, which you create by adding an identifier on to the class name . It takes the following pattern:

Constructors in Dart
ClassName.indentifierName()

From here on, this article will refer to a constructor without the identifier, that is, one which only uses the class name, as an unnamed constructor.

Why would you want a named constructor instead of the nice, tidy default one? Well, sometimes you have some common cases that you want to provide a convenience constructor for. Or maybe you have some special edge cases for constructing certain classes that need a slightly different approach.

Say, for example, that you want to have an anonymous user with a preset ID and name. You can do that by creating a named constructor. Add the following named constructor below the short-form constructor:

User.SecondConst(){
id = 0;
name = 'anonymous';
}

The identifier, or named part, of the constructor is .SecondConst. Named constructors may have parameters, but in this case, there are none. And since there aren’t any parameter names to get confused with, you don’t need to use this.id or this.name. Rather, you just use the property variables id and name directly.

Forwarding constructors

In the named constructor example above, you set the class properties directly in the constructor body, However this doesn’t follow the DRY principle you learned earlier. You’re repeating yourself by having two different locations where you can set the properties. It’s not a huge deal, but imagine that you have five different constructors instead of two. It would be easy to forget to update all give if you had to make a change, and if the constructor logic were complicated, it would be easy to make a mistake.

One way to solve this issue is by calling the main constructor from the named constructor. This is called forwarding or redirecting. To do that, you use the keyword this again.

Delete the anonymous named constructor that you created above and replace it with the following:

Constructors in Dart

This time there’s no constructor body, but instead, you follow the name with a colon and then forward the properties on to the unnamed constructor. The forwarding syntax replaces User with this.

Also, now that you’ve moved property initialization from the constructor body to the parameter list, Dart is finally convinced that id and name are guaranteed to be initialized. Replace these two lines:

int id = 0;
String name = " ";

with this following:

int id;
String name;

No complaints from Dart.

Private variables

Dart allows you to make variables private by adding an underscore(_) in front of their name.

Change the id property to _id and name to _name. Since these variables are used in several locations throughout your code, let VS Code help you out. Put your cursor on the variable name and press F2. Edit the variable name and press Enter to change all of the reference at once.

Constructors in Dart

Oh…, that actually renamed a few more things than you intended since it also renamed what was in the main function. But that’s OK. Just delete everything inside the body of main for now.

There is still one problem left with the unnamed constructor in User:

Constructors in Dart

The compiler gives you an error:

Named parameters can't start with an underscore. 

Fix that by deleting the unnamed constructor and replacing it with the following:

Constructors in Dart

Do you see the color that precedes _id? The comma separated list that comes after it is called the initializer list.
One use for this list is exactly what you’ve done here.
Externally, the parameters have one name, while internally, you’re using private variable names.

The initializer list is always executed before the body of the constructor, if the body exists. You don’t need a body for this constructor, but if you wanted to add one, it would look like this:

Constructors in Dart

The constructor would initialize _id and _name before it ran the print statement inside the braces.

Factory constructors

All of the constructors that you’ve seen up until now have been generative constructors. Dart also provides another type of constructor called a factory constructor.

A factory constructor provides more flexibility in how you create your objects. A generative constructor can only create a new instance of the class itself. However, factory constructors can return existing instances of the class, or even subclasses of it. This is useful when you want to hide the implementation details of a class from the code that uses it.

The factory constructor is basically a special method that starts with the factory keyword and returns an object of the class type. For example, you could add the following factory constructor to your User class:

Constructors in Dart

The factory method uses the generative constructor to create and return a new instance of User. You could also accomplish the same thing with a named constructor, though.

A more common example you’ll see is using a factory constructor to make a fromJson method:

Constructors in Dart

You would create a User object form the constructor like so:

Constructors in Dart

The factory constructor body allows you to perform some work before returning the new object, without exposing the inner wiring of that instantiation process to whoever is using the class.

Constructor summary

Since there are so many ways that constructors can very, here’s a brief comparison.

Constructors can be:

  • Forwarding or non-forwarding
  • Named or unnamed
  • Generative or factory
  • Constant or not constant

Check out more articles related to Dart Tutorial:

Functions in Dart

Loop in Dart

Switch Statement in Dart

Control Flow in Dart

String in Dart

Type Inference Variable in Dart | Dart Tutorial #2

Dart Tutorial is for Beginners from Scratch #1

Leave a Reply

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

Back To Top