Last updated
Apr 3, 2025
10 mins read
Share on

Build 10x products in minutes by chatting with AI - beyond just a prototype.

Software Development Executive - II
A Flutter and iOS developer with 3+ years of experience. Looking forward to each new thing in tech. Wandering like Alice.

Software Development Executive - II
Passionate Flutter developer crafting engaging mobile experiences. Turning coffee into beautiful UIs and bad jokes into commit messages. When not coding, he is probably debugging his life decisions.
In Dart, an object-oriented programming language, constructors are a fundamental concept that every developer must understand. Constructors are special methods that are automatically invoked when an object is instantiated, playing a crucial role in the initialization of new instances of a class.
A Dart constructor has the same name as its class and can be parameterized. If a class does not define a constructor, Dart implicitly provides a default constructor with no parameters. This default constructor calls the no-argument constructor in the superclass.
By the end of this blog, you'll have a solid understanding of constructors in Dart, enabling you to leverage them effectively in your Dart programming journey. Dart constructors will equip you with the knowledge you need to create and manage class instances effectively.
In Dart, constructors play a crucial role in the creation and initialization of objects. A default constructor is one such type of constructor that Dart provides implicitly if no constructor is defined in the class.
A default constructor is a constructor that doesn't take any parameters. If a class doesn't explicitly define a constructor, Dart implicitly provides a default constructor. This default constructor has no arguments and invokes the superclass's no-argument constructor.
class Car { // This is a default constructor Car() { print('An instance of the Car class is created'); } } void main() { var car = new Car(); // An instance of the Car class is created }
The primary role of a default constructor is to initialize the class's instance variables during object creation. The default constructor does this by automatically calling the superclass's constructor first before executing its own body. This ensures that the instance is properly set up.
class Car { String name; int age; // This is a default constructor Car() { name = 'Unknown'; age = 0; print('An instance of the Car class is created'); } } void main() { var car = new Car(); // An instance of the Car class is created print(car.name); // Unknown print(car.age); // 0 }
Let's see the default constructor in action with the Car and Animal classes. When we create a new instance of Car or Animal, the default constructor is automatically called, initializing the name and age instance variables.
class Animal { String name; int age; // This is a default constructor Animal() { name = 'Unknown'; age = 0; print('An instance of the Animal class is created'); } } void main() { var car = new Car(); // An instance of the Car class is created print(car.name); // Unknown print(car.age); // 0 var animal = new Animal(); // An instance of the Animal class is created print(animal.name); // Unknown print(animal.age); // 0 }
Default constructors can also be used to assign default values to instance variables. This is particularly useful when you want to ensure that your objects are in a valid state right after their creation.
class Car { String name; int age; // This is a default constructor Car() { name = 'Unknown'; age = 0; } } void main() { var car = new Car(); // An instance of the Car class is created print(car.name); // Unknown print(car.age); // 0 }
In the above example, the Car class's default constructor assigns the string 'Unknown' to the name instance variable and 0 to the age instance variable. This ensures that every new Car instance has a valid state.
In Dart, constructors are not limited to the default ones. Dart offers the ability to define named constructors that allow a class to have multiple constructors.
Named constructors are unique to Dart. They allow a class to have multiple constructors, each identified by a different name. Named constructors are created by defining a constructor with the class name followed by the constructor name.
Let's see the named constructor in action with the Person and Animal classes. When we create a new instance of Person or Animal using the named constructor, the named constructor is called, initializing the name and age instance variables.
The real power of named constructors comes into play when you want to create different instances of a class in different ways. For example, you might want to create a Person instance with default values, or you might want to create a Person instance with specific values.
Named constructors can also be used to assign default values to instance variables, just like default constructors. This is particularly useful when you want to ensure that your objects are in a valid state right after their creation.
In the above example, the Person class's named constructor assigns the string 'Unknown' to the name instance variable and 0 to the age instance variable. This ensures that every new Person instance created using the named constructor has a valid state.
Dart provides a unique feature that allows a class to have more than one constructor. This includes default, named, and factory constructors.
In Dart, a class can have multiple constructors to allow the creation of objects in different ways. This is particularly useful when you want to provide flexibility in object creation. For example, you might want to create an instance with default values, specific values, or based on some condition.
Implementing multiple constructors in Dart is straightforward. You can define a default constructor and as many named constructors as you need.
Factory constructors are another type of constructor in Dart. Unlike the default and named constructors, the factory constructor doesn't always create a new instance of its class. Instead, it can return an instance from a cache or return an instance of a subtype.
Let's see the factory constructor in action. In the following example, the Car class has a factory constructor that always returns the same instance.
In this example, car1 and car2 are the same instance. This demonstrates that the factory constructor doesn't always create a new instance of its class.
In Dart, constructors are not limited to default, named, and factory types. Dart also provides constant and redirecting constructors.
A constant constructor allows you to create compile-time constants. If a class produces objects that never change, you can get better performance by using a constant constructor.
Constant constructors are used to create instances that can be determined at compile-time. This is particularly useful when creating immutable classes.
A redirecting constructor has no body; instead, it uses this keyword followed by other constructors.
Implementing redirecting constructors in Dart allows for more flexible and readable code. You can define a constructor that redirects to another constructor in the same class.
In the above example, the Car.unknown() constructor redirects to the default constructor, creating a Car instance with the name 'Unknown' and age 0.
In conclusion, constructors in Dart play a pivotal role in object initialization, offering a flexible way to create and manage class instances. Dart provides various types of constructors - default, named, factory, constant, and redirecting, each with unique features and uses. Understanding these constructors is crucial for effective Dart programming, as they ensure objects are always in a valid state right after creation, leading to robust and efficient solutions.
class Person {
String name;
int age;
// This is a named constructor
Person.namedConstructor() {
name = 'Unknown';
age = 0;
print('An instance of the Person class is created using a named constructor');
}
}
void main() {
var person = new Person.namedConstructor();
// An instance of the Person class is created using a named constructor
}class Animal {
String name;
int age;
// This is a named constructor
Animal.namedConstructor() {
name = 'Unknown';
age = 0;
print('An instance of the Animal class is created using a named constructor');
}
}
void main() {
var person = new Person.namedConstructor();
// An instance of the Person class is created using a named constructor
print(person.name); // Unknown
print(person.age); // 0
var animal = new Animal.namedConstructor();
// An instance of the Animal class is created using a named constructor
print(animal.name); // Unknown
print(animal.age); // 0
}class Person {
String name;
int age;
// Default constructor
Person() {
name = 'Unknown';
age = 0;
}
// Named constructor
Person.withValues(this.name, this.age);
}
void main() {
var person1 = new Person(); // An instance of the Person class is created with default values
print(person1.name); // Unknown
print(person1.age); // 0
var person2 = new Person.withValues('John Doe', 25);
// An instance of the Person class is created with specific values
print(person2.name); // John Doe
print(person2.age); // 25
}class Person {
String name;
int age;
// This is a named constructor
Person.namedConstructor() {
name = 'Unknown';
age = 0;
}
}
void main() {
var person = new Person.namedConstructor();
// An instance of the Person class is created using a named constructor
print(person.name); // Unknown
print(person.age); // 0
}class Car {
String name;
int age;
// Default constructor
Car() {
name = 'Unknown';
age = 0;
}
// Named constructor
Car.withValues(this.name, this.age);
}class Car {
String name;
int age;
// Default constructor
Car() {
name = 'Unknown';
age = 0;
}
// Named constructor
Car.withValues(this.name, this.age);
// Another named constructor
Car.namedConstructor() {
name = 'Car';
age = 1;
}
}
void main() {
var car1 = new Car(); // An instance of the Car class is created with default values
print(car1.name); // Unknown
print(car1.age); // 0
var car2 = new Car.withValues('Tesla', 2022);
// An instance of the Car class is created with specific values
print(car2.name); // Tesla
print(car2.age); // 2022
var car3 = new Car.namedConstructor();
// An instance of the Car class is created using another named constructor
print(car3.name); // Car
print(car3.age); // 1
}class Car {
static final Car _instance = Car._internal();
// Factory constructor
factory Car() {
return _instance;
}
// Named constructor
Car._internal();
}
void main() {
var car1 = new Car();
var car2 = new Car();
print(identical(car1, car2)); // true
}void main() {
var car1 = new Car();
var car2 = new Car();
print(identical(car1, car2)); // true
}class Car {
final String name;
final int age;
// This is a constant constructor
const Car(this.name, this.age);
}
void main() {
const car = Car('Tesla', 2022); // A constant instance of the Car class is created
}void main() {
const car = Car('Tesla', 2022); // A constant instance of the Car class is created
print(car.name); // Tesla
print(car.age); // 2022
}class Car {
String name;
int age;
// Default constructor
Car(this.name, this.age);
// Redirecting constructor
Car.unknown() : this('Unknown', 0);
}
void main() {
var car = new Car.unknown(); // An instance of the Car class is created using a redirecting constructor
print(car.name); // Unknown
print(car.age); // 0
}void main() {
var car = new Car.unknown(); // An instance of the Car class is created using a redirecting constructor
print(car.name); // Unknown
print(car.age); // 0
}