Dart/Flutter: Multiple constructor overloading examples

In java, multiple constructors can be defined and overloaded. Constructors are used to initializing the fields of a class during object creation.

Dart does not support an overload of functions and constructors and does not allow multiple functions/constructors of the same name with different arguments.

A Dart class can have only one Default or unnamed constructor. Default constructor syntax:

class Classname{
    fields
    // default one construcotr
    Classname(fields)
}

default constructor Example

class Employee {
  final int id;
  final String name;

  // Default or unnamed constructor
  Employee(this.id, this.name);

}

if you declare or overload multiple constructors as given below

class Employee {
  final int id;
  final String name;

  // Default or unnamed constructor
  Employee(this.id, this.name);
  Employee(this.id);

}

void main() {
  print("getEnumNames(WEEK.values)");
}

It gives a compilation error

Error: ‘Employee’ is already declared in this scope. Employee(this.id); ^^^^^^^^ lib/main.dart:6:3: Info: Previous declaration of ‘Employee’. Employee(this.id, this.name); ^^^^^^^^ Then, How do implement multiple constructors in Dart?

named constructor is the way to implement multiple constructors apart from the default constructor Dart supports the constructor in two ways.

  • default and unnamed constructor: Allows only one constructor
  • named constructor: Allows multiple constructors

Dart multiple constructor examples

named constructors can be declared by adding more constructors to a class.

You can create multiple constructors with the constructor name. Each named constructor has a unique name

class Classname{
    fields
    // default one construcotr
    Classname(fields)
    Classname.unnamedconstructor(Classname other) :
    // fields initialization
}

Here is a Multiple constructor example in dart

class Employee {
  int _id = 0;
  String _name = "";

  // Default or unnamed constructor
  Employee() {}

  // named overloaded constructor
  Employee.copy(Employee emp) {
    this._id = emp._id;
    this._name = emp._name;
  }
  // named overloaded constructor
  Employee.changeData(int id, String name) {
    this._id = id;
    this._name = name;
  }
  String toString() {
    String output = "Id:: " + _id.toString() + " , " + "Name - " + _name;
    return output;
  }
}

void main() {
  // calls the default constructor
  Employee emp = new Employee();
  print(emp.toString());
// calls named constructor
  Employee emp1 = new Employee.copy(emp);

  print(emp1.toString());
// calls named constructor
  Employee emp2 = new Employee.changeData(1, "John");
  print(emp2.toString());
}

Output:

Name -  , Id:: 0
Name -  , Id:: 0
Name - John , Id:: 1

Another way, you can use factory constructors and static methods to achieve multiple constructor functionality

Factory named constructor

You can also define factory and static constructors with an overloaded version using the named constructor

// named factory  constructor
  factory Employee.factoryconstructor() {
    return Employee.changeData(1, "franc");
  }

  // named static  constructor
  static Employee staticConstructor() {
    return Employee.changeData(1, "franc");
  }

You can call the factory and static constructor using the below code

// calls factory named constructor
  Employee emp3 =Employee.factoryconstructor();
  print(emp3.toString());

// calls static named constructor
  Employee emp4 = Employee.staticConstructor();
  print(emp4.toString());

Here is an

class Employee {
  int _id = 0;
  String _name = "";

  // Default or unnamed constructor
  Employee() {}

  // named overloaded constructor
  Employee.copy(Employee emp) {
    this._id = emp._id;
    this._name = emp._name;
  }
  // named overloaded constructor
  Employee.changeData(int id, String name) {
    this._id = id;
    this._name = name;
  }
  String toString() {
    String output = "Id:: " + _id.toString() + " , " + "Name - " + _name;
    return output;
  }

  // named factory  constructor
  factory Employee.factoryconstructor() {
    return Employee.changeData(1, "franc");
  }

  // named static  constructor
  static Employee staticConstructor() {
    return Employee.changeData(1, "franc");
  }
}

void main() {
  // calls the default constructor
  Employee emp = new Employee();
  print(emp.toString());
// calls named constructor
  Employee emp1 = new Employee.copy(emp);

  print(emp1.toString());
// calls named constructor
  Employee emp2 = new Employee.changeData(1, "John");
  print(emp2.toString());

  // calls factory named constructor
  Employee emp3 =Employee.factoryconstructor();
  print(emp3.toString());

// calls static named constructor
  Employee emp4 = Employee.staticConstructor();
  print(emp4.toString());

}

Multiple Named constructor inheritance example

Default behavior

If you have super and subclass in inheritance hierarchy classes. Constructor in subclass calls superclass constructor in case of default and named constructor

Here is an example that calls the constructor in the parent and child default constructor

  • initializes data if required
  • calls superclass constructor first
  • Next, calls the subclass constructor
class Employee {
  int _id = 0;
  String _name = "";

  // Default or unnamed constructor
  Employee() {
    print("Employee constructor");
  }
}

class AdminEmployee extends Employee {
  // Default or unnamed constructor
  AdminEmployee() {
    print("AdminEmployee constructor");
  }
}

void main() {
  // calls default Employee constructor
  Employee emp = new Employee();
  // calls default parent  and child constructor
  AdminEmployee emp1 = new AdminEmployee();
}

Next, In the case of the named constructor, Create a superclass named constructor followed by a colon(:)and call the subclass named constructor

It calls following order when superclass is called

  • Calls subclass named constructor
  • calls superclass named constructor Here is an example
class Employee {
  int _id = 0;
  String _name = "";

  // Default or unnamed constructor
  Employee() {
    print("Employee constructor");
  }
  // named constructor subclass
  Employee.copy() {
    print('Child Named constructor ');
  }
}

class AdminEmployee extends Employee {
  // Default or unnamed constructor
  AdminEmployee() {
    print("AdminEmployee constructor");
  }
  // named constructor superclass
  AdminEmployee.copy() : super.copy() {
    print('Parent Named constructor');
  }
}

void main() {
  // calls default Employee constructor
  Employee emp = new Employee();
  // calls default parent  and child constructor
  AdminEmployee emp1 = new AdminEmployee();
  AdminEmployee emp2 = AdminEmployee.copy();
}

Output:

Employee constructor
Employee constructor
AdminEmployee constructor
Child Named constructor
Parent Named constructor