Constructor overbelasting in Java – best practice

Er zijn een paar soortgelijke onderwerpen, maar ik kon er geen vinden met een voldoende antwoord.

Ik zou graag willen weten wat de beste werkwijze is voor overbelasting van de constructor in Java. Ik heb al mijn eigen gedachten over het onderwerp, maar ik zou graag meer advies horen.

Ik verwijs naar zowel constructoroverbelasting in een eenvoudige klasse als constructoroverbelasting terwijl een reeds overbelaste klasse wordt geërfd (wat betekent dat de basisklasse overbelaste constructors heeft).

Bedankt 🙂


Antwoord 1, autoriteit 100%

Hoewel er geen “officiële richtlijnen” zijn, volg ik het principe van KISS en DRY. Maak de overbelaste constructors zo eenvoudig mogelijk, en de eenvoudigste manier is dat ze dit alleen (…) noemen. Op die manier hoeft u de parameters maar één keer te controleren en af te handelen.

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

Vanuit het oogpunt van unit-testing wordt het gemakkelijk om de klasse te testen, omdat je de bronnen erin kunt stoppen. Als de klas veel bronnen heeft (of medewerkers zoals sommige OO-nerds het noemen), overweeg dan een van deze twee dingen:

Maak een 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
}

De constructor in Simple hoeft alleen de parameter SimpleParamste splitsen:

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

…of maak SimpleParamseen attribuut:

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

Maak een fabrieksklasse

Maak een fabrieksklasse die de bronnen voor u initialiseert, wat gunstig is als het initialiseren van de bronnen een beetje moeilijk is:

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

De constructor wordt dan op dezelfde manier gedaan als bij de parameterklasse:

public Simple(ResourceFactory factory) {
    this(factory.createR1(), factory.createR2());
} 

Maak een combinatie van beide

Ja… je kunt op beide manieren mixen en matchen, afhankelijk van wat op dat moment gemakkelijker voor je is. Parameterklassen en eenvoudige fabrieksklassen zijn vrijwel hetzelfde, gezien de klasse Simpledat ze op dezelfde manier worden gebruikt.


Antwoord 2, autoriteit 42%

Ik denk dat het het beste is om enkele primaire constructorte hebben waarnaar de overbelaste constructors verwijzen door this()aan te roepen met de relevante parameterstandaarden. De reden hiervoor is dat het veel duidelijker maakt wat de geconstrueerde staatvan het object is – je kunt de primaire constructor eigenlijk zien als de enige echte constructor, de anderen delegeren het gewoon

Een voorbeeld hiervan is JTable– de primaire constructor neemt een TableModel(plus kolom- en selectiemodellen) en de andere constructors noemen deze primaire constructor.

>

Voor subklassen waar de superklasse al overbelaste constructors heeft, zou ik geneigd zijn aan te nemen dat het redelijk is om een van de constructors van de bovenliggende klasse als primairte behandelen en te denken dat het volkomen legitiem om geen enkele primaire constructor te hebben. Als ik bijvoorbeeld Exceptionuitbreid, geef ik vaak 3 constructors, waarvan de ene slechts een String-bericht gebruikt, de andere een Throwable-oorzaak en de andere die beide. Elk van deze constructors roept superrechtstreeks aan.


Antwoord 3, autoriteit 4%

Als je een zeer complexe klasse hebt met veel opties waarvan slechts enkele combinaties geldig zijn, overweeg dan om een Builder te gebruiken. Werkt erg goed, zowel codegewijs als logisch.

De Builder is een geneste klasse met methoden die alleen zijn ontworpen om velden in te stellen, en dan neemt de constructor ComplexClass alleen zo’n Builder als argument.


Bewerken: de ComplexClass-constructor kan ervoor zorgen dat de status in de Builder geldig is. Dit is erg moeilijk te doen als je alleen setters op ComplexClass gebruikt.


Antwoord 4

Het hangt echt af van het soort klassen, aangezien niet alle klassen gelijk zijn gemaakt.

Als algemene richtlijn zou ik 2 opties willen voorstellen:

  • Voor waarde & onveranderlijkeklassen (uitzondering, geheel getal, DTO’s en dergelijke) gebruiken enkele primaire constructorzoals gesuggereerd in het bovenstaande antwoord
  • Gebruik voor al het andere (sessionbeans, services, veranderlijke objecten, JPA- en JAXB-entiteiten enzovoort) alleen standaardconstructormet verstandige standaardwaarden voor alle eigenschappen, zodat deze zonder aanvullende configuratie kan worden gebruikt

Antwoord 5

Overbelasting van constructeurs is vergelijkbaar met overbelasting van methoden. Constructors kunnen worden overbelast om objecten op verschillende manieren te maken.

De compiler maakt onderscheid tussen constructors op basis van het aantal argumenten dat aanwezig is in de constructor en andere parameters, zoals de volgorde waarin de argumenten worden doorgegeven.

Ga voor meer informatie over Java-constructor naar https://tecloger.com/constructor-in -java/


Antwoord 6

Nou, hier is een voorbeeld voor overbelaste constructeurs.

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

In het bovenstaande voorbeeld zie je overbelaste constructors. De naam van de constructors is hetzelfde, maar elke constructor heeft verschillende parameters.

Hier zijn enkele bronnen die meer licht werpen op overbelasting van constructeurs in Java,

Constructeurs.

Other episodes