Frage an java, constructor-overloading, constructor, overloading – Überladen von Konstruktoren in Java - Best Practice

100

Es gibt ein paar ähnliche Themen, aber ich konnte keine mit einer ausreichenden Antwort finden.

Ich möchte wissen, was die beste Vorgehensweise zum Überladen von Konstruktoren in Java ist. Ich habe bereits meine eigenen Gedanken zu diesem Thema, würde aber gerne weitere Ratschläge erhalten.

Ich beziehe mich sowohl auf das Überladen von Konstruktoren in einer einfachen Klasse als auch auf das Überladen von Konstruktoren, während eine bereits überladene Klasse geerbt wird (was bedeutet, dass die Basisklasse Konstruktoren überladen hat).

Vielen Dank :)

Deine Antwort

5   die antwort
6

von denen nur einige Kombinationen gültig sind, ziehen Sie die Verwendung eines Builders in Betracht. Funktioniert sowohl codeweise als auch logisch sehr gut.

Der Builder ist eine verschachtelte Klasse mit Methoden, die nur zum Festlegen von Feldern entwickelt wurden, und der ComplexClass-Konstruktor verwendet einen solchen Builder nur als Argument.

Bearbeiten: Der ComplexClass-Konstruktor kann sicherstellen, dass der Status im Builder gültig ist. Dies ist sehr schwierig, wenn Sie nur Setter für ComplexClass verwenden.

Ich stimme dem Builder-Muster sehr zu. Überladene Konstruktoren wie das OP sind keine gute Idee, da sie das Prinzip der geringsten Überraschung verfehlen. Martin Spamer
2

da nicht alle Klassen gleich sind.

Als allgemeine Richtlinie würde ich 2 Optionen vorschlagen:

ZumWert & unveränderlich Klassen (Exception, Integer, DTOs und solche) verwendeneinzelner primärer Konstruktor wie in der obigen Antwort vorgeschlagenFür alles andere (Session-Beans, Services, veränderbare Objekte, JPA- und JAXB-Entitäten usw.) verwendenNur Standardkonstruktor mit sinnvollen Vorgaben für alle Eigenschaften, so dass es ohne zusätzliche Konfiguration verwendet werden kann
0

Hier ist ein Beispiel für überladene Konstruktoren.

public class Employee
{
   private String name;
   private int age;

   public Employee()
   {
      System.out.println("We are inside Employee() constructor");
   }

   public Employee(String name)
   {
      System.out.println("We are inside Employee(String name) constructor");
      this.name = name;
   }

   public Employee(String name, int age)
   {
      System.out.println("We are inside Employee(String name, int age) constructor");
      this.name = name;
      this.age = age;
   }

   public Employee(int age)
   {
      System.out.println("We are inside Employee(int age) constructor");
      this.age = age; 
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }

   public int getAge()
   {
      return age;
   }

   public void setAge(int age)
   {
      this.age = age;
   }
}

Im obigen Beispiel sehen Sie überladene Konstruktoren. Der Name der Konstruktoren ist derselbe, aber jeder Konstruktor hat andere Parameter.

Hier sind einige Ressourcen, die mehr Aufschluss über das Überladen von Konstruktoren in Java geben:

Konstruktoren.

Konstruktor Erklärung.

Es scheint, als wäre sehr viel weniger Mühe darauf verwendet worden, diese Antwort zu schreiben. Und das OP weiß, was Konstruktorüberladung ist. Die Antwort erklärt genau das. rockydgeekgod
73

einzelner primärer Konstruktor auf die die überladenen Konstruktoren durch Aufruf verweisenthis() mit den entsprechenden Standardparametern. Der Grund dafür ist, dass es viel klarer macht, was das istkonstruierter Zustand der Gegenstand ist - wirklich können Sie sich den Primärerbauer als vorstellennur echter Konstruktor, delegieren die anderen nur dazu

Ein Beispiel dafür könnte seinJTable - Der primäre Konstruktor nimmt aTableModel (plus Spalten- und Auswahlmodelle) und die anderen Konstruktoren nennen diesen primären Konstruktor.

Für Unterklassenwo die Superklasse bereits Konstruktoren überladen hatIch würde eher davon ausgehen, dass es vernünftig ist, einen der Konstruktoren der Elternklasse als zu behandelnprimär und denke, es ist absolut legitim, keinen einzigen primären Konstruktor zu haben. Zum Beispiel beim AusfahrenExceptionIch biete oft 3 Konstruktoren an, von denen einer nur einen nimmtString Nachricht, eine unter aThrowable Ursache und der andere nehmen beide. Jeder dieser Konstruktoren ruft aufsuper direkt.

Ja, das habe ich gemeint. Eyal Roth
Ich halte das für unnötig restriktiv. Tom Hawtin - tackline
Ich habe meine Antwort aus dieser Klarstellung geändert oxbow_lakes
Ich denke, "bereits überladene Klassen" bedeuteten, dass die Basisklasse mehrere überladene Konstruktoren hat. Chii
159

offiziellen Richtlinien" gibt, folge ich dem Prinzip von KISS und DRY. Machen Sie die überladenen Konstruktoren so einfach wie möglich, und der einfachste Weg ist, dass sie nur diese (...) aufrufen. Auf diese Weise müssen Sie die Parameter nur einmal und nur einmal überprüfen und handhaben.

public class Simple {

    public Simple() {
        this(null);
    }

    public Simple(Resource r) {
        this(r, null);
    }

    public Simple(Resource r1, Resource r2) {
        // Guard statements, initialize resources or throw exceptions if
        // the resources are wrong
        if (r1 == null) {
            r1 = new Resource();
        }
        if (r2 == null) {
            r2 = new Resource();
        }

        // do whatever with resources
    }

}

Vom Standpunkt des Unit-Tests aus wird es einfach, die Klasse zu testen, da Sie die Ressourcen in sie einfügen können. Wenn die Klasse über viele Ressourcen verfügt (oder Kollaborateure, wie es einige OO-Geeks nennen), sollten Sie eines der beiden folgenden Dinge berücksichtigen:

Erstellen Sie eine Parameterklasse
public class SimpleParams {
    Resource r1;
    Resource r2;
    // Imagine there are setters and getters here but I'm too lazy 
    // to write it out. you can make it the parameter class 
    // "immutable" if you don't have setters and only set the 
    // resources through the SimpleParams constructor
}

Der Konstruktor in Simple muss entweder nur das teilenSimpleParams Parameter:

public Simple(SimpleParams params) {
    this(params.getR1(), params.getR2());
}

... oder machenSimpleParams ein Attribut:

public Simple(Resource r1, Resource r2) {
    this(new SimpleParams(r1, r2));
}

public Simple(SimpleParams params) {
    this.params = params;
}
Mache eine Fabrikklasse

Erstellen Sie eine Factory-Klasse, die die Ressourcen für Sie initialisiert. Dies ist günstig, wenn das Initialisieren der Ressourcen etwas schwierig ist:

public interface ResourceFactory {
    public Resource createR1();
    public Resource createR2();
}

Der Konstruktor wird dann auf die gleiche Weise ausgeführt wie bei der Parameterklasse:

public Simple(ResourceFactory factory) {
    this(factory.createR1(), factory.createR2());
} 
Bilde eine Kombination aus beiden

Ja ... Sie können beide Möglichkeiten kombinieren, je nachdem, was für Sie gerade einfacher ist. Parameterklassen und einfache Factory-Klassen sind in Anbetracht derSimple Klasse, dass sie auf die gleiche Weise verwendet werden.

+1 sehr schöner Beitrag user12345613
Ist es möglich, mehrere Konstruktoren mit jeweils einem Parameter unterschiedlichen Typs zu erstellen? Like - neues Objekt (int aa) / neues Objekt (String bb)? Botea Florin
@JosieThompson Soweit ich weiß, ist dies in keinem Standard definiert. Ich bin damit einverstanden, dass es nützlich ist, zuerst den vollständigen Konstruktor zu haben, um alle Parameter einer Methode schnell zu sehen. Indem Sie sie jedoch nach der Anzahl der Argumente sortieren, können Sie den überladenen Aufrufen auf der Seite folgen, was sich natürlicher anfühlt, wenn Sie überlegen, wie wir Code lesen und schreiben. Matt
Ich habe in diesem und anderen Beispielen festgestellt, dass die Konstruktordefinitionen in der Reihenfolge geschrieben sind, in der die Argumente im Konstruktoraufruf am wenigsten oder am meisten verwendet werden. Ist das Standard-Java-Stil? Warum ?: Meiner Meinung nach ist es sinnvoll, das Gegenteil zu tun, so dass die erste Konstruktordefinition, die Sie sehen sollten, diejenige ist, die alle Details enthält. Josie Thompson

Verwandte Fragen