Frage von derJonesy, 39

Welche möglichkeit gibt es in Java für einen "universellen" Constructor?

Ich bin schon etwas eingerostet in Java und habe ein altes Projekt meinerseits geöffnet, welches ich etwas "aufräumen" will z.B. durch das Ersetzen überflüssiger Codezeilen.

Das Projekt heißt "CircledString": https://gyazo.com/864598fa059dd871f3c7bc1fd470518a


Im Grunde überliefere ich einfach ein Label (um auch die Textformatierung möglichst einfach beeinflussen zu können) und wenn gewollt noch die "thickness" und "Color" des Kreises.

Da man sich natürlich aussuchen können soll, ob man z.B. nur das Label oder das Label und die thickness oder das Label, Thickness und Color als Parameter angibt.

Dafür habe ich für jeden Fall einen Constructor mit sehr ähnlicher Funktion aufgesetzt:

public CircledString(JLabel label){ ... }
public CircledString(JLabel label, int thickness){ ... }
public CircledString(JLabel label, Color color){ ... }
public CircledString(JLabel label, int thickness, Color color){ ... }

Ich meine ich hätte früher mal von einem Weg gehört wie man den ausführlichsten Constructor schreiben kann und dann automatisch alle "kleineren Versionen" automatisch verwendbar sind. Gibt es da einen Weg den ich jetzt nicht im Kopf habe oder muss ich wirklich jede Version ausschreiben?

Antwort
von ceevee, 14

In deinem Falle würde ich ein Konfigurationsobjekt anlegen, welches thickness, color, usw... enthält. Denn wenn wir das mal erweitern, dass der Konstruktor

public CircledString(JLabel label, int thickness, int padding, int margin, Color color){ ... }

 , dann hast du ein Problem - wie sollen jeweils die Konstruktoren aussehen, bei denen nur Label und thickness bzw. nur Label und padding gesetzt sind, aussehen? 

Damit wärst du dann bei 2 Konstrukturen (einmal nur das Label als Pflichtparameter und einmal das Label und das Konfigurationsobjekt). Im Konstruktor musst du dich dann darum kümmern, dass fehlende Werte im Konstruktionsobjekt durch Standardwerte ersetzt werden (oder du stattest das Konfigurationsobjekt mit einer Methode dazu aus).

Expertenantwort
von KnusperPudding, Community-Experte für Java, 11

Interessant Frage, jedoch hätte ich hierfür jedoch mehrere Antworten parat.

Eine Option wäre, du verwendest direkt mehrere Konstruktoren, so wie du es selbst beschrieben hast, dein "Haupt-Konstruktor" ist der ausführlichste:

public CircledString(JLabel label){ this(label, null, null); }
public CircledString(JLabel label, int thickness){ this.(label, thickness, null); }
public CircledString(JLabel label, int thickness, Color color){ this.label = label; ... }

Eine andere Option ist, wie bereits in einer anderen Antwort genannt: Varars: 

public CircledString(JLabel label, String... param){
    ...
}

Wobei du beim aufrufen zwangsläufig ein Label mit angeben kannst, jedoch beliebig viele Parametern. z.B.:

new CircledString(label, "Value1");
new CircledString(label, "Value1", "Value2");

Eine weitere Möglichkeit wäre: Du verwendest als Parameter eine Klasse, von der alle deine möglichen Argumente ableiten. z.B.: Object.

Dann nimmst du eine Typen-Prüfung vor um zu schauen, wohin der Parameter passt (Macht nur Sinn, wenn alle Parameter von unterschiedlichen Typen sind):

public CircledString(JLabel label, Object param) {
this.(label, 
((param instanceof Integer) ? (int) param : null),
((param instanceof Color) ? (Color) param : null)
)
}

Zuletzt fällt mir nur noch eine Option ein, bei der du eine eigene Property Klasse als Parameter übergibst, für die du dann entsprechende Werte setzen kannst, Farbe, Dicke, Schriftart, etc.

Antwort
von Spirit528, 18

Du kannst nur die Anzahl von Parametern gleicher Typen variabel machen:

http://javabeginners.de/Grundlagen/variable\_Methodenparameter.php

public CircledString(JLabel label, Integer... values)

Also lässt sich bei deinem Fall wohl eher schlecht anwenden.

Du kannst aber einen neuen Typ durch eine eigene Klasse erschaffen und dann immer drauf prüfen ob der Wert (Attribut) gesetzt wurde oder nicht.
Dann wird dem CircledString-Konstruktur nur noch ein Objekt instanziert aus dieser Klasse übergeben und man benötigt nur noch einen Konstruktor.

Keine passende Antwort gefunden?

Fragen Sie die Community