A constructor is a special feature in a class in the Dart programming language. It sets up the variables of the class. Constructors are named after the class itself. Unlike regular methods, constructors don't have a return type. If you don't write a constructor in a class, Dart automatically creates a basic one without any arguments.
There are three main types of constructors in Dart:
Default Constructor: This is the simple, no-argument constructor that's automatically created if you don't make one yourself.
Named Constructor: This type lets you have multiple different constructors in the same class with different names.
Parameterized Constructor: This kind of constructor can take arguments, allowing you to set up your class with different initial values.
Factory Constructor: This is a special type of constructor that can be used to return an instance of a class.
When we don't initialize any constructor inside a class, The class itself initializes a default constructor.
Eg:
main(){
var emp = Employee();
}
class Employee {
Employee(){
print('Hello Employee');
}
}
When we run the above program, The main method automatically initializes the default constructor and prints Hello Employee
Eg:
main(){
var emp = Employee(123, 'Aditya', 'Mobile apps developer');
print('User Id ${emp.id}..... User Name ${emp.name}.......User Designation ${emp.designation}');
}
class Employee {
int id = 0;
String name = '';
String designation = '';
Employee(int id, String name, String designation ){
this.id = id;
this.name = name;
this.designation = designation;
}
}
// Output: User Id 123..... User Name Aditya.......User Designation Mobile apps developer
Constructor overloading is not possible in dart programming to achieve this we use a named constructor.
Eg:
main(){
var empBasicInfo = Employee.basicInfo(123, 'Aditya', 'Mobile Apps Developer');
var empBirthDetails = Employee.birthDetails('29-Feb-1988', 'Narasaraopet', 'O+Ve');
print(empBasicInfo.name);
print(empBirthDetails.birthDay);
}
class Employee {
int id = 0;
String name = '';
String designation = '';
String birthDay = '';
String placeOfBirth = '';
String bloodGroup = '';
Employee.birthDetails(this.birthDay, this.placeOfBirth, this.bloodGroup);
Employee.basicInfo(this.id, this.name, this.designation );
}
//Output: Aditya
//Output: 29-Feb-1988
A factory constructor is a special way to make objects in programming. Unlike normal ways that always make a new object, a factory constructor can sometimes give us back an object that already exists. It can also decide to make a new one depending on the situation. This is handy for certain programming patterns, like when we only want one instance of something (Singleton) or when we want to be in charge of how and when our objects are made.
Here's a simple example to illustrate a factory constructor in action:
class DBConnection {
static DBConnection? _instance;
// Private constructor
DBConnection._internal();
// The factory constructor
factory DBConnection() {
// The '??=' operator assigns a value to '_instance' if it is null
_instance ??= DBConnection._internal();
return _instance!;
}
void connect() {
// Method to connect to the database
print('Connected to the database!');
}
}
void main() {
var db1 = DBConnection();
var db2 = DBConnection();
print(identical(db1, db2)); // This will print 'true'
db1.connect(); // This will print 'Connected to the database!'
}
In the above example, DBConnection is a class that makes a connection to a database. Let's discuss a few points on the above program
The constructor DBConnection._internal() is designated as private, and therefore, it is not accessible from outside the class.
The factory constructor DBConnection() is designed to first determine if an instance of DBConnection (_instance) already exists. If such an instance is present, it returns this existing instance. Otherwise, it proceeds to create a new instance by utilizing the private constructor.
In the main() function, when db1 and db2 are instantiated using DBConnection(), they both reference the same instance, adhering to the Singleton pattern. This is confirmed by the call to identical(db1, db2), which returns true, indicating that db1 and db2 are indeed the same instance.
This pattern guarantees that regardless of the number of attempts to create a new DBConnection, you always obtain the same instance. This approach is particularly beneficial for managing resources such as database connections, where it is generally preferable to have a single connection that is shared throughout your application.