飞镖多个构造函数

时间:2018-04-06 10:54:29

标签: dart flutter

是否真的无法在dart中为类创建多个构造函数?

在我的Player类中,如果我有这个构造函数

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

然后我尝试添加这个构造函数:

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

我收到以下错误:

  

已定义默认构造函数。

我没有通过创建一个带有一堆非必需参数的构造函数来寻找解决方法。

有解决这个问题的好方法吗?

8 个答案:

答案 0 :(得分:42)

您只能拥有一个未命名 constructor,但您可以拥有任意数量的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);

这个构造函数可以简化

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

  Player(this._name, this._color);

命名构造函数也可以是私有的,可以使用_

开始名称
class Player {
  Player._(this._name, this._color);

  Player._foo();
}

答案 1 :(得分:2)

如果您的班级使用最终参数,则接受的答案将不起作用。这样做:

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

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

答案 2 :(得分:1)

如果您已经在项目中使用了带参数的构造函数,现在您发现不需要一些参数默认构造函数,则可以添加一个空的构造函数。

class User{
String name;

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

答案 3 :(得分:1)

我找到了解决此问题的方法,具体取决于检查传递给函数的数据类型

尝试这个Solution

答案 4 :(得分:1)

您可以使用factory constructors

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

@GünterZöchbauer已经说过

在Flutter中,您只能有一个未命名的构造函数,但可以有任意数量的其他已命名的构造函数。

  • 通过使用命名构造函数,您可以在同一类中创建多个构造函数。
  • 每个构造函数都有一个唯一的名称。这样您就可以识别每个人。

命名构造函数的语法

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

更多见解,Click Here

了解Flutter Click Here中的各种类型的构造函数

答案 7 :(得分:0)

您想拥有多个构造函数的情况如何?例如,您要使用2个构造函数:

Customer(String name, int age, String location) {
  this.name = name;
  this.age = age;
  this.location = location;
}

Customer(this.name, this.age) {
  this.name = name;
  this.age = age;
}

但是,如果您同时在一个类中定义它们,则会出现编译器错误。

Dart提供的命名构造函数可帮助您更清晰地实现多个构造函数:

class Customer {
  // ...

  Customer(String name, int age, String location) {
    this.name = name;
    this.age = age;
    this.location = location;
  }

  // Named constructor - for multiple constructors
  Customer.withoutLocation(this.name, this.age) {
    this.name = name;
    this.age = age;
  }

  Customer.empty() {
    name = "";
    age = 0;
    location = "";
  }

  @override
  String toString() {
    return "Customer [name=${this.name},age=${this.age},location=${this.location}]";
  }
}

您可以使用语法糖更简单地编写它:

Customer(this.name, this.age, this.location);

Customer.withoutLocation(this.name, this.age);

Customer.empty() {
  name = "";
  age = 0;
  location = "";
}

现在我们可以通过这些方法创建新的Customer对象。

var customer = Customer("bezkoder", 26, "US");
print(customer);
// Customer [name=bezkoder,age=26,location=US]

var customer1 = Customer.withoutLocation("zkoder", 26);
print(customer1);
// Customer [name=zkoder,age=26,location=null]

var customer2 = Customer.empty();
print(customer2);
// Customer [name=,age=0,location=]

那么,有什么方法可以使Customer.empty()变得更整洁? 以及如何在调用Customer.withoutLocation()而不是null时初始化位置字段的空值?

来自:Multiple Constructors