Dart Mehrere Konstruktoren


76

Ist es wirklich nicht möglich, mehrere Konstruktoren für eine Klasse in Dart zu erstellen?

in meiner Spielerklasse, wenn ich diesen Konstruktor habe

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

Dann versuche ich diesen Konstruktor hinzuzufügen:

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

Ich erhalte folgende Fehlermeldung:

Der Standardkonstruktor ist bereits definiert.

Ich suche keine Problemumgehung, indem ich einen Konstruktor mit einer Reihe nicht erforderlicher Argumente erstelle.

Gibt es eine gute Möglichkeit, dies zu lösen?


1
Als nicht verwandten Kommentar sollten Sie wahrscheinlich Getter für colorund name, nicht getColor()und getName()Methoden verwenden. Wenn sich die Werte nie ändern, können Sie ein einzelnes öffentliches Feld wie verwenden class Player { final String name; final int color; Player(this.name, this.color); }.
lrn

Ich bin neu im Dart und noch nicht an diese Art von Standards gewöhnt, aber danke, ich werde es versuchen.
Tom Porat

Dies ist auch der Zeitpunkt, an dem Sie feststellen, dass alle Cribbing-Anfänger während des Überladens von Java / C # -Konstruktoren gearbeitet haben ... >> "Es braucht Zeit, um die Schönheit hinter Java & C # zu enträtseln"!
Yo Apps

Antworten:


147

Sie können nur einen unbenannten Konstruktor haben , aber Sie können eine beliebige Anzahl zusätzlicher benannter Konstruktoren haben

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

Dieser Konstruktor kann vereinfacht werden

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

zu

  Player(this._name, this._color);

Benannte Konstruktoren können auch privat sein, indem Sie den Namen mit beginnen _

class Player {
  Player._(this._name, this._color);

  Player._foo();
}

Konstruktoren mit finalFeldinitialisiererliste sind erforderlich:

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

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

1
Danke vielmals! Genau das, wonach ich gesucht habe.
Tom Porat

4

Wenn Ihre Klasse endgültige Parameter verwendet, funktioniert die akzeptierte Antwort nicht. Das macht:

class Player {
  final String name;
  final String color;

  Player(this.name, this.color);

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

2

Wenn Sie bereits einen Konstruktor mit Parametern im Projekt verwendet haben und jetzt herausgefunden haben, dass Sie einen Standardkonstruktor ohne Parameter benötigen, können Sie einen leeren Konstruktor hinzufügen.

class User{
String name;

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

1

Versuchen Sie den folgenden Code auf 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());
}


0

Wie @ Günter Zöchbauer schon sagte

Sie können nur einen unbenannten Konstruktor haben, aber Sie können eine beliebige Anzahl zusätzlicher benannter Konstruktoren in Flutter haben.

  • Mit dem benannten Konstruktor können Sie mehrere Konstruktoren in derselben Klasse erstellen.
  • Jeder Konstruktor hat einen eindeutigen Namen. Damit Sie jeden von ihnen identifizieren können.

Syntax für benannten Konstruktor :

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

Für weitere Einblicke klicken Sie hier

Um mehr über verschiedene Arten von Konstruktoren in Flutter zu erfahren, klicken Sie hier


0

Wie wäre es mit dem Fall, dass Sie mehr als einen Konstruktor haben möchten? Zum Beispiel gibt es 2 Konstruktoren, die Sie verwenden möchten:

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

Wenn Sie jedoch beide in einer Klasse definieren, tritt ein Compilerfehler auf.

Dart bietet einen benannten Konstruktor, mit dem Sie mehrere Konstruktoren klarer implementieren können:

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

Mit Syntactic Sugar können Sie es einfacher schreiben:

Customer(this.name, this.age, this.location);

Customer.withoutLocation(this.name, this.age);

Customer.empty() {
  name = "";
  age = 0;
  location = "";
}

Jetzt können wir Customermit diesen Methoden ein neues Objekt erstellen .

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=]

Gibt es eine Möglichkeit, Customer.empty()ordentlich zu machen ? Und wie initialisiere ich einen leeren Wert für das Standortfeld, wenn ich Customer.withoutLocation()anstelle von nullanrufe?

Von: Mehrere Konstruktoren

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.