Dart 多个构造函数

问题描述 投票:0回答:11

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

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

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

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

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

我收到以下错误:

默认构造函数已经定义。

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

有什么好的方法可以解决这个问题吗?

dart flutter
11个回答
273
投票

您只能拥有一个 unnamed constructor,但您可以拥有任意数量的附加 named 构造函数

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

12
投票

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

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

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

5
投票

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

class User{
String name;

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

3
投票

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

3
投票

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

2
投票

您可以使用工厂构造函数

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

0
投票

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

试试这个解决方案


0
投票

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

了解更多见解点击这里

了解Flutter中各类构造函数点击这里


0
投票

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


0
投票

如果你想做一些更复杂的属性计算(我是一个 Swift 人),你可以这样做:

class FooProvider {
  int selectedFoo;

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

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

0
投票

试试这个: 将需要传递给其他构造函数的属性作为可选属性。

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";
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.