Dart 多个构造函数

Posted

技术标签:

【中文标题】Dart 多个构造函数【英文标题】:Dart Multiple Constructors 【发布时间】:2018-09-16 09:15:39 【问题描述】:

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

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

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

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

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

我收到以下错误:

默认构造函数已经定义。

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

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

【问题讨论】:

作为不相关的评论,您可能应该对colorname 使用getter,而不是getColor()getName() 方法。如果值永远不会改变,您可以使用单个公共字段,例如 class Player final String name; final int color; Player(this.name, this.color); 我是飞镖新手,还没有习惯这种标准,但是谢谢,我会试一试的。 这也是当您意识到 Java/C# 构造函数重载期间所有蹩脚的初学者所做的... >> “揭开 Java 和 C# 背后的美丽需要时间”! 【参考方案1】:

您只能拥有一个未命名的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();

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

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 Player 
  final String name;
  final String color;

  Player(this.name, this.color);

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

【讨论】:

【参考方案3】:

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

class User
String name;

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

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

您可以使用factory constructors

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

【讨论】:

【参考方案6】:

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

试试这个Solution

【讨论】:

【参考方案7】:

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

更多见解Click Here

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

【讨论】:

请说明我是否在某个地方弄错了,以便我改进或删除答案。【参考方案8】:

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

【讨论】:

【参考方案9】:

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

【讨论】:

这个问题有八个现有答案,包括一个获得最高票数、获得两百票的已接受答案。你确定你的解决方案还没有给出吗?如果不是,您为什么认为您的方法改进了已被社区验证的现有提案?在 Stack Overflow 上,提供解释总是很有用,但在问题已得到解决且让 OP 和社区都满意的情况下,它尤其很重要。通过解释您的答案有何不同以及何时可能更受欢迎,帮助读者了解答案。

以上是关于Dart 多个构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Dart 工厂构造函数 - 它与“const”构造函数有何不同

如何在 Dart 中调用超级构造函数?

Dart类(构造函数、单例)

Dart:Dart 如何匹配类的构造函数中的命名参数?

在 Dart 中使用带有构造函数的 Setter

Dart Constructors 构造函数使用技巧整理