Dart 多重构造函数

真的不可能在 dart 中为一个类创建多个构造函数吗?

如果我有这个构造函数

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

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

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

我得到以下错误:

缺省构造函数已定。

我不想通过创建一个包含大量非必需参数的构造函数来寻找变通方法。

有什么好办法解决这个问题吗?

83314 次浏览

你只能有一个 无名氏 构造函数,但你可以有任何数量的额外 < strong > 命名的 构造函数

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

需要具有 final字段初始值设定项列表的构造函数:

class Player {
final String name;
final String color;


Player(this.name, this.color);


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

如果你已经在项目中使用了一个带 params 的构造函数,现在你发现你需要一些没有 params 的缺省构造函数,你可以添加一个空的构造函数。

class User{
String name;


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

如果您的类使用最终参数,则接受的答案将不起作用:

class Player {
final String name;
final String color;


Player(this.name, this.color);


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

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

正如 Günter Zö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

更多见解

了解颤振 点击这里中各种类型的构造函数

我已经找到了解决这个问题的办法取决于检查的数据类型,你传递给函数

试试这个 解决方案

你可以使用 工厂建筑工人

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

Dart 不支持参数重载(具有多个同名但不同参数的函数)。这也适用于构造函数——这就是为什么在 SDK 中有这么多带有命名构造函数的类。

在 Dart 中,你可以使用缺省构造函数、命名构造函数、工厂方法和静态方法来实例化类:

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

产出:

1
2
_3
!4

Class User{
User();
User.fromName(this.name);
      

String? name;
}

如果你想做一些更详细的属性计算(我是 Swift 的家伙) ,你可以这样做:

class FooProvider {
int selectedFoo;


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


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