'Dart Multiple Constructors

Is it really not possible to create multiple constructors for a class in dart?

in my Player Class, If I have this constructor

Player(String name, int color) {
    this._color = color;
    this._name = name;
}

Then I try to add this constructor:

Player(Player another) {
    this._color = another.getColor();
    this._name = another.getName();
}

I get the following error:

The default constructor is already defined.

I'm not looking for a workaround by creating one Constructor with a bunch of non required arguments.

Is there a nice way to solve this?



Solution 1:[1]

You can only have one unnamed constructor, but you can have any number of additional named constructors

class Player {
  Player(String name, int color) {
    this._color = color;
    this._name = name;
  }

  Player.fromPlayer(Player another) {
    this._color = another.getColor();
    this._name = another.getName();
  }  
}

new Player.fromPlayer(playerOne);

This constructor can be simplified

  Player(String name, int color) {
    this._color = color;
    this._name = name;
  }

to

  Player(this._name, this._color);

Named constructors can also be private by starting the name with _

class Player {
  Player._(this._name, this._color);

  Player._foo();
}

Constructors with final fields initializer list are necessary:

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

  Player.fromPlayer(Player another) :
    color = another.color,
    name = another.name;
}

Solution 2:[2]

If your class uses final parameters the accepted answer will not work. This does:

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

  Player.fromPlayer(Player another) :
    color = another.color,
    name = another.name;
}

Solution 3:[3]

If you already used a constructor with params in the project and now you figured out that you need some no params default constructor you can add an empty constructor.

class User{
String name;

   User({this.name}); //This you already had before
   User.empty(); //Add this later 
}

Solution 4:[4]

Try the below code on DartPad

class MyClass {
  //These two are private attributes
  int _age;
  String _name;

  //This is a public attribute
  String defaultName = "My Default Name!";

  //Default constructor
  MyClass() {
    _age = 0;
    _name = "Anonymous";
  }

  MyClass.copyContructor(MyClass fromMyClass) {
    this._age = fromMyClass._age;
    this._name = fromMyClass._name;
  }

  MyClass.overloadedContructor(String name, int age) {
    this._age = age;
    this._name = name;
  }

  MyClass.overloadedContructorNamedArguemnts({String name, int age}) {
    this._age = age;
    this._name = name;
  }

  //Overriding the toString() method
  String toString() {
    String retVal = "Name:: " + _name + " | " + "Age:: " + _age.toString();
    return retVal;
  }
}

//The execution starts from here..
void main() {
  MyClass myClass1 = new MyClass();

  //Cannot access oprivate attributes
  //print(myClass1.name);
  //print(myClass1.age);

  //Can access the public attribute
  print("Default Name:: " + myClass1.defaultName);

  print(myClass1.toString());

  MyClass myClass2 = new MyClass.copyContructor(myClass1);

  print(myClass2.toString());

  MyClass myClass3 = new MyClass.overloadedContructor("Amit", 42);

  print(myClass3.toString());

  MyClass myClass4 =
      new MyClass.overloadedContructorNamedArguemnts(age: 42, name: "Amit");

  print(myClass4.toString());
}

Solution 5:[5]

You can use factory constructors

factory Player.fromPlayer(Player another) => Player(another.name, another.color);

Solution 6:[6]

Dart doesn't support parameter overloading (having multiple functions of the same name but with different parameters). This applies to constructors as well - that's the reason why in SDK there're so many classes with named constructors.

In Dart you can use Default Constructor, Named Constructor, Factory Method and Static Method to instantiate classes:

class A {
  // Default constructor
  A() : msg = '1';
  
  // Named constructor with positional param
  A.message(this.msg);
  
  // Factory method with named param
  factory A.underscore({String msg = ''}) {
    return A.message('_'+msg);
  }
  
  // Factory method with arrow func body
  static A bang(msg) => A.message('!'+msg); 
  
  final String msg;
}

void main() {
  print(A().msg);
  print(A.message('2').msg);
  print(A.underscore(msg: '3').msg);
  print(A.bang('4').msg);
}

Output:

1
2
_3
!4

Solution 7:[7]

i had found solution to solve this problem depend on checked the type of data you are passed it to function

Try this Solution

Solution 8:[8]

As Günter Zöchbauer already specified in his answer:

You can only have one unnamed constructor, but you can have any number of additional named constructors in Flutter.

  • By using named constructor you can create multiple constructors in the same class.
  • Each constructor will have a unique name. So that you can identify each of them.

Syntax for named constructor :

class_name.constructor_name (arguments) { 
   // If there is a block of code, use this syntax

   // Statements
}

or

class_name.constructor_name (arguments); 
   // If there is no block of code, use this syntax

For more insights Click Here

To know about various types of constructors in Flutter Click Here

Solution 9:[9]

Class User{
      User();
      User.fromName(this.name);
      
      String? name;
    }

Solution 10:[10]

If you want to do some more elaborated property calculation (I'm a Swift guy), you can do like this:

class FooProvider {
  int selectedFoo;

  FooProvider(List<String> usageObjects)
      : selectedFoo = firstOne(usageObjects);

  static int firstOne(List<String> usageObjects) {
    return 2;
  }
}