Design Converter
Education
Software Development Executive - I
Software Development Executive - II
Last updated on Oct 19, 2023
Last updated on Oct 19, 2023
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.
1class Car { 2 // This is a default constructor 3 Car() { 4 print('An instance of the Car class is created'); 5 } 6} 7 8void main() { 9 var car = new Car(); // An instance of the Car class is created 10}
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.
1class Car { 2 String name; 3 int age; 4 5 // This is a default constructor 6 Car() { 7 name = 'Unknown'; 8 age = 0; 9 print('An instance of the Car class is created'); 10 } 11} 12 13void main() { 14 var car = new Car(); // An instance of the Car class is created 15 print(car.name); // Unknown 16 print(car.age); // 0 17}
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.
1class Animal { 2 String name; 3 int age; 4 5 // This is a default constructor 6 Animal() { 7 name = 'Unknown'; 8 age = 0; 9 print('An instance of the Animal class is created'); 10 } 11} 12 13void main() { 14 var car = new Car(); // An instance of the Car class is created 15 print(car.name); // Unknown 16 print(car.age); // 0 17 18 var animal = new Animal(); // An instance of the Animal class is created 19 print(animal.name); // Unknown 20 print(animal.age); // 0 21}
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.
1class Car { 2 String name; 3 int age; 4 5 // This is a default constructor 6 Car() { 7 name = 'Unknown'; 8 age = 0; 9 } 10} 11 12void main() { 13 var car = new Car(); // An instance of the Car class is created 14 print(car.name); // Unknown 15 print(car.age); // 0 16}
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.
1class Person { 2 String name; 3 int age; 4 5 // This is a named constructor 6 Person.namedConstructor() { 7 name = 'Unknown'; 8 age = 0; 9 print('An instance of the Person class is created using a named constructor'); 10 } 11} 12 13void main() { 14 var person = new Person.namedConstructor(); 15 // An instance of the Person class is created using a named constructor 16}
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.
1class Animal { 2 String name; 3 int age; 4 5 // This is a named constructor 6 Animal.namedConstructor() { 7 name = 'Unknown'; 8 age = 0; 9 print('An instance of the Animal class is created using a named constructor'); 10 } 11} 12 13void main() { 14 var person = new Person.namedConstructor(); 15 // An instance of the Person class is created using a named constructor 16 print(person.name); // Unknown 17 print(person.age); // 0 18 19 var animal = new Animal.namedConstructor(); 20 // An instance of the Animal class is created using a named constructor 21 print(animal.name); // Unknown 22 print(animal.age); // 0 23}
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.
1class Person { 2 String name; 3 int age; 4 5 // Default constructor 6 Person() { 7 name = 'Unknown'; 8 age = 0; 9 } 10 11 // Named constructor 12 Person.withValues(this.name, this.age); 13} 14 15void main() { 16 var person1 = new Person(); // An instance of the Person class is created with default values 17 print(person1.name); // Unknown 18 print(person1.age); // 0 19 20 var person2 = new Person.withValues('John Doe', 25); 21 // An instance of the Person class is created with specific values 22 print(person2.name); // John Doe 23 print(person2.age); // 25 24}
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.
1class Person { 2 String name; 3 int age; 4 5 // This is a named constructor 6 Person.namedConstructor() { 7 name = 'Unknown'; 8 age = 0; 9 } 10} 11 12void main() { 13 var person = new Person.namedConstructor(); 14 // An instance of the Person class is created using a named constructor 15 print(person.name); // Unknown 16 print(person.age); // 0 17}
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.
1class Car { 2 String name; 3 int age; 4 5 // Default constructor 6 Car() { 7 name = 'Unknown'; 8 age = 0; 9 } 10 11 // Named constructor 12 Car.withValues(this.name, this.age); 13}
Implementing multiple constructors in Dart is straightforward. You can define a default constructor and as many named constructors as you need.
1class Car { 2 String name; 3 int age; 4 5 // Default constructor 6 Car() { 7 name = 'Unknown'; 8 age = 0; 9 } 10 11 // Named constructor 12 Car.withValues(this.name, this.age); 13 14 // Another named constructor 15 Car.namedConstructor() { 16 name = 'Car'; 17 age = 1; 18 } 19} 20 21void main() { 22 var car1 = new Car(); // An instance of the Car class is created with default values 23 print(car1.name); // Unknown 24 print(car1.age); // 0 25 26 var car2 = new Car.withValues('Tesla', 2022); 27 // An instance of the Car class is created with specific values 28 print(car2.name); // Tesla 29 print(car2.age); // 2022 30 31 var car3 = new Car.namedConstructor(); 32 // An instance of the Car class is created using another named constructor 33 print(car3.name); // Car 34 print(car3.age); // 1 35}
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.
1class Car { 2 static final Car _instance = Car._internal(); 3 4 // Factory constructor 5 factory Car() { 6 return _instance; 7 } 8 9 // Named constructor 10 Car._internal(); 11} 12 13void main() { 14 var car1 = new Car(); 15 var car2 = new Car(); 16 17 print(identical(car1, car2)); // true 18}
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.
1void main() { 2 var car1 = new Car(); 3 var car2 = new Car(); 4 5 print(identical(car1, car2)); // true 6}
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.
1class Car { 2 final String name; 3 final int age; 4 5 // This is a constant constructor 6 const Car(this.name, this.age); 7} 8 9void main() { 10 const car = Car('Tesla', 2022); // A constant instance of the Car class is created 11}
Constant constructors are used to create instances that can be determined at compile-time. This is particularly useful when creating immutable classes.
1void main() { 2 const car = Car('Tesla', 2022); // A constant instance of the Car class is created 3 print(car.name); // Tesla 4 print(car.age); // 2022 5}
A redirecting constructor has no body; instead, it uses this keyword followed by other constructors.
1class Car { 2 String name; 3 int age; 4 5 // Default constructor 6 Car(this.name, this.age); 7 8 // Redirecting constructor 9 Car.unknown() : this('Unknown', 0); 10} 11 12void main() { 13 var car = new Car.unknown(); // An instance of the Car class is created using a redirecting constructor 14 print(car.name); // Unknown 15 print(car.age); // 0 16}
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.
1void main() { 2 var car = new Car.unknown(); // An instance of the Car class is created using a redirecting constructor 3 print(car.name); // Unknown 4 print(car.age); // 0 5}
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.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.