Tom Porat
Tom Porat

Reputation: 1652

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?

Upvotes: 163

Views: 111412

Answers (11)

amitsriv99
amitsriv99

Reputation: 143

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());
}

Upvotes: 4

Hoosam Meray
Hoosam Meray

Reputation: 1

Try this: make the properties you need to pass to the other constructor as optionals.

class Person{
  String name;
  int? age;

  Person(this.name, this.age);

  Person.veryOld(this.name){
    age = 60;
  }

  @override String toString() {
    return "name: $name\nage: $age";
  }
}

Upvotes: 0

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657128

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

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

can be simplified 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;
}

Upvotes: 278

Rudolf J
Rudolf J

Reputation: 517

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;
  }
}

Upvotes: 0

Ahmad Abdullah
Ahmad Abdullah

Reputation: 141

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

Upvotes: 0

Maxim Saplin
Maxim Saplin

Reputation: 4652

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

Upvotes: 3

Faruk
Faruk

Reputation: 5821

You can use factory constructors

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

Upvotes: 2

Deepam Gupta
Deepam Gupta

Reputation: 2692

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

Upvotes: 0

Mahmoud Salah Eldin
Mahmoud Salah Eldin

Reputation: 2098

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

Try this Solution

Upvotes: 0

Quentin
Quentin

Reputation: 838

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;
}

Upvotes: 12

Moti Bartov
Moti Bartov

Reputation: 3592

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 
}

Upvotes: 5

Related Questions