Dart多个构造函数


80

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

在我的播放器类中,如果我有此构造函数

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

然后,我尝试添加此构造函数:

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

我收到以下错误:

默认构造函数已经定义。

我不是通过创建带有一堆不需要的参数的构造函数来寻找解决方法。

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


1
作为不相关的评论,您可能应该为color和而name不是getColor()getName()方法使用getter 。如果值永远不变,则可以使用单个公共字段,例如class Player { final String name; final int color; Player(this.name, this.color); }
lrn

我是dart的新手,还没有习惯这种标准,但是,谢谢,我会尝试一下。
Tom Porat

这也是您意识到Java / C#构造函数重载期间所有all脚的初学者所做的事情……>>“花费时间来揭示Java和C#背后的美丽”!
Yo Apps

Answers:


154

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

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

1
非常感谢!正是我想要的。
汤姆·波拉特

5

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

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

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

2

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

class User{
String name;

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

1

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


-1

正如@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

了解更多信息,请点击这里

要了解Flutter中的各种类型的构造函数,请单击此处


-1

您想拥有多个构造函数的情况如何?例如,您希望使用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提供了Named构造函数,可帮助您更清晰地实现多个构造函数:

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

来自:多个构造函数

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.