Sitemap
Arte Bi

Arte Bi

Dart: Constructors

4 min readFeb 10, 2025

This article is part of a series on How to start creating mobile applications for Android or iOS using Dart & Flutter.

Press enter or click to view image in full size
Photo by Rick Mason on Unsplash

Introduction

Constructor is a special type of function for creating an instance of a class and initializing its state. Because a constructor is a function, when describing constructor parameters, you can follow the same rules as for functions. The constructor’s name corresponds to the class name.

Next, an example of creating and using a simple constructor:

void main() {
// Call the constructor: Profile(int profileAge, String profileName)
Profile profile = Profile(18, 'no name');
profile.printInfo();
}

class Profile{
// Constructir with two params: profileAge and profileName
Profile(int profileAge, String profileName) {
age = profileAge;
name = profileName;
}

int age = 0;
String name = '';

void printInfo() {
print('Name:$name, Age:$age');
}
}

The constructor above can be shortened by using the this keyword. this is a reference to the current instance of the class. Through this keyword, we can access the variables, methods of an object, and also call its constructors.

void main() {
// Call the constructor
Profile profile = Profile(18, 'no name');
profile.printInfo();
}

class Profile {
// Constructir with two params: profileAge and profileName
Profile(this.age, this.name);

int age = 0;
String name = '';

void printInfo() {
print('Name:$name, Age:$age');
}
}

A class can contain only one constructor with the same name as the class.

class Profile {
// Constructir with two params: profileAge and profileName
Profile(this.age, this.name);

// You will receive an error.
// Declaring a second constructor with name 'Profile' is not allowed."
Profile(this.age) {
name = 'no name';
}

int age = 0;
String name = '';

void printInfo() {
print('Name:$name, Age:$age');
}
}

Named constructors

Same constructor as described above, but after the class name and dot, you need to specify a name.

void main() {
// Call the constructor
Profile profile_1 = Profile(22, 'Jack');
profile_1.printInfo();

Profile profile_2 = Profile.onlyAge(18);
profile_2.printInfo();

Profile profile_3 = Profile.onlyName('Harry');
profile_3.printInfo();
}

class Profile {
// Constructir with two params: profileAge and profileName
Profile(this.age, this.name);

// Named constructor 'onlyName'
Profile.onlyName(this.name) {
age = 0;
}

// Named constructor 'onlyAge'
Profile.onlyAge(this.age) {
name = 'no name';
}

int age = 0;
String name = '';

void printInfo() {
print('Name:$name, Age:$age');
}
}

You can create as many named constructors as needed, but the names must be unique.

Get Arte Bi’s stories in your inbox

Join Medium for free to get updates from this writer.

Initializer list

You can initialize class fields before the constructor body. The initializer is specified after the constructor’s name and parameters, following a colon. If there are multiple initializers, they are separated by commas.

void main() {

/*
Result will be: Name:Jack, Age:73
because constructor 'Profile(Map<String, String> profileInfo)'
has initializer before constructor's body
*/
Profile profile1 = Profile({'name': 'Jack', 'age': '73'});

/*
Result will be: Name:Ali, Age:0
because constructor 'Profile.age(Map<String, String> profileInfo)'
has initializer before constructor's body
*/
Profile profile2 = Profile.name({'name': 'Ali'});

Profile profile3 = Profile.age({'age': '50'});
profile3.printInfo();
}

class Profile {
Profile(Map<String, String> profileInfo)
: name = profileInfo['name']!, // Initializing 'name'
age = int.parse(profileInfo['age']!) { // Initializing 'age'
printInfo();
}

Profile.name(Map<String, String> profileInfo)
: name = profileInfo['name']! { // Initializing 'name'
printInfo();
}

Profile.age(Map<String, String> profileInfo)
: age = int.parse(profileInfo['age']!); // Initializing 'age'

int age = 0;
String name = '';

void printInfo() {
print('Name:$name, Age:$age');
}
}

Factory constructors

Allows returning existing instances or creating an object based on custom logic.

void main() {
var db1 = Database();
var db2 = Database();

// identical - this function checks
// whether two references refer to the same object.
print(identical(db1, db2)); // in console will be - true
}

class Database {
static final Database _instance = Database._internal();

// Private constructor
Database._internal();

// Factory cinstructor
// Each call of the given constructor does not create a new object
// but returns an already existing one, "_instance".
factory Database() {
return _instance;
}

void connect() {
print("connect...");
}
}
void main() {
var db1 = Database("sql");
db1.connect(); // Console output will be: connection string for sql

var db2 = Database("i don't know");
db2.connect(); // Console output will be: connection string for postgreSql
}

class Database {
Database.SQL() {
connectionString = "connection string for sql";
}

Database.PostgreSQL() {
connectionString = "connection string for postgreSql";
}

late String connectionString;

// Factory cinstructor
factory Database(String dbName) {
if (dbName == "sql") {
return Database.SQL();
}

return Database.PostgreSQL();
}

void connect() {
print(connectionString);
}
}

Redirecting constructors

One constructor can call another constructor. To call the next constructor, use ‘this’ after ‘:’ .

void main() {
// In this case, constructor A is simply called.
var profileA = Profile(name: 'John', age: 43, countryCode: 'US');
profileA.printInfo(); // Age:43, name:John, country code:US

// Here, we call constructor B, which in turn calls constructor A.
var profileB = Profile.onlyName('Wilson');
profileB.printInfo(); // Age:0, name:Wilson, country code:-

}

class Profile {
// Let's call this constructor 'A'
Profile({required this.name, required this.age, required this.countryCode});

// This is constructor 'B'
// As a result, the object created by constructor A will be returned.
Profile.onlyName(String name) : this(name: name, age: 0, countryCode: '-');

final String name;
final int age;
final String countryCode;

void printInfo() {
print('Age:$age, name:$name, country code:$countryCode');
}
}

Constructor by default

If you didn’t define a constructor when creating a class, Dart will create it. This will be a constructor that takes no parameters.

class Person {
int age = 0;
String name = '';
}

// For this class Dart will create the next constructor: Person();

--

--