【问题标题】:Dart Multiple ConstructorsDart 多个构造函数
【发布时间】: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# 背后的美丽需要时间”!

标签: dart flutter


【解决方案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 和社区都满意的情况下,它尤其很重要。通过解释您的答案有何不同以及何时可能更受欢迎,帮助读者了解答案。
              猜你喜欢
              • 2018-12-03
              • 1970-01-01
              • 1970-01-01
              • 2020-05-05
              • 1970-01-01
              • 2021-12-25
              • 1970-01-01
              • 2014-11-03
              • 1970-01-01
              相关资源
              最近更新 更多