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?

Tom Porat
quelle
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;
}
Günter Zöchbauer
quelle
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;
}
QUentin
quelle
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 
}
Moti Bartov
quelle
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());
}
amitsriv99
quelle
1

Ich hatte eine Lösung gefunden, um dieses Problem zu lösen. Dies hängt davon ab, welche Art von Daten Sie an die Funktion übergeben

Versuchen Sie diese Lösung

Mahmoud Salah Eldien Säbel
quelle
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

Genius
quelle
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

Paresh Mangukiya
quelle