2009-03-06 2 views
2

Ich bin ziemlich neu in Java und von Python und PHP bin ich zu Standardwerten für Funktionsparameter gewöhnt.Ist Überladen wirklich die einzige Möglichkeit, Standardwerte für Methodenparameter in Java zu erhalten?

So habe ich eine Angewohnheit, Methoden zu schreiben, die aus etwas anderen Situationen, in denen Sie nur einige der Werte festlegen möchten, aufgerufen werden sollen. Zum Beispiel wäre dies in meinem PHP-Code üblich, wo ich Factory-Methoden habe, die Objektinstanzen mit leicht unterschiedlichen Eigenschaften bereitstellen.

In Java, so scheint es, muss ich eine Methode haben, die alle Parameter und dann mehrere überladene Varianten erwartet, die diese Methode mit einigen der Parameter aufrufen würden, die auf Standardeinstellungen gesetzt sind, und einige, die vom Aufrufer bereitgestellt werden. Was ist, naja, OK, kann mir aber manchmal auf die Nerven gehen.

Ich erinnere mich, dass mich das schon bei einigen kurzen Exkursionen nach C++ und ActionScript geärgert hat. Haben nun erfahrene Java-Entwickler eine Abkürzung dafür?

Es scheint mir, dass technisch die Frage durch die Summe aller Beiträge als "Ja, es ist" beantwortet wurde. Ich habe unten einen Wiki-Eintrag geöffnet, um die verschiedenen alternativen Lösungen zu sammeln. Bitte trage ein wenn du magst. Ich fand alle diese sehr hilfreich als Inspiration und als Lernbeispiele für typische Java-Konstrukte.

Antwort

0

Es scheint, wie: „Ja, es ist“, außer:

ähnliche Effekte mit varargs erreicht werden könnten, wie von Paul Whelan oder durch die Festlegung eine zusätzliche Art trägt die Parameter wie Felder mit den richtigen Standardwerten vorgeschlagen als vorgeschlagen von Jon Skeet. Boris Pavlović fügt hinzu, dass sein Typ eine innere statische Klasse sein könnte, um die Dinge ordentlich am richtigen Ort zu halten.

Cons (Beachten Sie, dass diese ganze Frage nicht um schwerwiegende Folgen ist, nur um bequem zwickt):

varargs am besten geeignet scheint, eine Liste mit variabler Länge von Werten für das Bestehen, die sehr ähnliche Form und meist gleichwertige Bedeutung haben wie eine Liste von Namen. Wenn die Methode für den in der Frage angegebenen Zweck verwendet würde, müsste sie verschiedene Listen überprüfen, um sie zu interpretieren, was nicht mehr, aber weniger praktisch erscheint.

Ein spezieller Typ, der die Parameter enthält, scheint am nützlichsten zu sein, wenn der resultierende Typ andere Verwendungen haben kann, als nur an eine bestimmte Methode übergeben zu werden, oder wenn es sich um komplexere Parameter handelt. Wenn es 2-4 Parameter gibt und einige Standardwerte haben, scheint es immer noch etwas bequemer zu überladen, aber das könnte eine Frage des persönlichen Geschmacks sein.

3

siehe varargs

http://www.java-tips.org/java-se-tips/java.lang/using-the-varargs-language-feature.html

(Aktualisiert URL; dieser Kommentar hinzugefügt, da Stackoverflow erfordert> 30 Zeichen)

+1

scheint als sein Missbrauch der varargs Eigenschaft zu mir. – erikkallen

+0

+1 zu erikkallens Kommentar. –

+0

Ich finde varargs sind gut, wenn die Argumente in der Anzahl variieren, aber alle bedeuten das gleiche, wie mit der Liste der Namen in diesen Beispielen. Wenn die Argumente etwas anderes bedeuten, müssen Sie bald so viele Überprüfungen durchführen, dass es sauberer und leichter zu überladen ist. Recht? –

7

Eine weitere Option ist eine Variante des Builder-Muster - Sie haben eine Art, die darstellt, alle Parameter, konstruiere eine Instanz dieses Typs (entsprechend voreingestellt), setze die gewünschten Eigenschaften und übergebe dann das Ergebnis an die ursprüngliche Methode oder füge eine Methode im "Parametertyp" hinzu, um die Methode für dich aufzurufen.

Sie können dies in den Standardbibliotheken mit den Klassen ProcessBuilder und in Aktion sehen.

+0

Ja, das könnte für einige Situationen gut sein, werde ich es im Hinterkopf behalten. Wenn ich jedoch mit einem Typ komme, der nur als Argument für eine einzige Methode nützlich ist, denke ich, dass es etwas zu peinlich ist. Ich bleibe dabei, diese zu überladen. –

+0

@Hanno Fietz Sie können den Typ als statische innere Klasse im Objekt deklarieren, in dem die Methode deklariert wurde. Zögere nicht, Typen zu erstellen. Sie sind kostenlos in Java :) –

+0

Netter Hinweis auch, Boris. Vielen Dank. –

0

Solange Sie in OO-Code codieren, werden Sie keine Standardwerte in Java verpassen. Standardargumente sind nur im prozeduralen Codierungsstil nützlich.

In OO, anstatt den Status durch die Methoden/Prozeduren zu übergeben, befindet sich der Status bereits in dem Objekt, das Sie aufrufen, oder die Objekte, die Sie als Parameter übergeben. Die meiste Zeit benötigen Sie nicht mehr als 1 oder 2 Parameter in Ihren Methoden.

Wenn Sie das Objekt vor der Verwendung konfigurieren möchten, würden Sie es mit einem einfachen Konstruktor konstruieren und dann verschiedene Setter aufrufen. Dies macht den Code viel lesbarer (weil Sie die Setter-Namen sehen), verglichen mit dem Aufruf eines Konstruktors mit vielen Argumenten. Und wenn ein neues Attribut später kommt, können Sie Ihrem Objekt hinzufügen, ohne Ihre vorhandenen Factory-Methoden ändern zu müssen.

1

Es kann sehr schwierig sein zu versuchen, Ihren Prozess von einer Sprache in eine andere zu übersetzen. Sie können, wie andere bereits gesagt haben, einige Arbeiten ausführen, um vielleicht das zu bekommen, was Sie wollen ... aber je eher Sie "akzeptieren", wie Java funktioniert, desto besser ist es, wenn Sie in Java arbeiten.

Ich musste einige PHP-Sachen machen ... genervt mich zu keinem Ende, dass ich es nicht tun konnte, was ich wollte ... so geht es in beide Richtungen.

Das größte Hindernis, auf das Sie stoßen werden, ist wahrscheinlich die statische Typisierung. Es gibt Dinge, die Sie versuchen können, um es zu umgehen, aber am Ende werden sie ein sehr großer Hack sein.

In den frühen Tagen von C++ versuchten Leute, C++ zu überzeugen, sich wie Smalltalk zu benehmen ... hat nicht gut geklappt. In den frühen Tagen, wenn Java Leute versuchten, ihr C++ Wissen zu nehmen und es in Java zu benutzen ... funktionierte nicht besonders gut (was doppelt frustrierend ist, da die Sprachen auf der Oberfläche sehr ähnlich sind).

Mein Rat, für Ihre Java-Programmierung lernen, wie ein Java-Entwickler und nicht ein PHP-Entwickler zu programmieren.

Für Ihr unmittelbares Problem, ist es möglich, dass Sie wirklich unterschiedliche Klassen von der Fabrik neu abstimmen sollten, anstatt die gleiche Art von Objekt mit verschiedenen Variablen zu erstellen?

+0

+1 für den letzten Kommentar –

+0

"Mein Rat, für Ihre Java-Programmierung lernen, wie ein Java-Entwickler und nicht ein PHP-Entwickler zu programmieren." - +1 dafür. Klingt so, als ob der Fokus zu sehr auf Funktionen und Parametern liegt, die übergeben werden, anstatt auf Objekte und den internen Zustand. – duffymo

+0

Verstehen Sie mich nicht falsch, ich habe nichts gegen verschiedene Konzepte in Sprachen, ich wählte Java sorgfältig für dieses Projekt und ich bin glücklich mit meiner Wahl. Ich habe mich hauptsächlich gefragt, ob das die Sprache oder ein Missverständnis auf meiner Seite ist. –

2

Um das zu vereinfachen, habe ich eine Annotation für Standardwerte und einen Annotationsprozessor erstellt, der eine Superklasse mit den überladenen Methoden generiert. Zum Beispiel:

protected void process(
    Processor processor, 
    String item, 
    @Default("Processor.Size.LARGE") Size size, 
    @Default("red") String color, 
    @Default("1") int quantity) { 
     ... 
} 

, die (in einer dynamisch erzeugten Super) erzeugen

protected void process(sample.Processor processor, java.lang.String item) { 
    process(processor, item, Processor.Size.LARGE, "red", 1); 
} 
protected void process(sample.Processor processor, 
         java.lang.String item, 
         sample.Processor.Size size) { 
    process(processor, item, size, "red", 1); 
} 
protected void process(sample.Processor processor, 
         java.lang.String item, 
         sample.Processor.Size size, 
         java.lang.String color) { 
    process(processor, item, size, color, 1); 
} 
protected abstract void process(sample.Processor processor, 
           java.lang.String item, 
           sample.Processor.Size size, 
           java.lang.String color, 
           int quantity) ; 

Siehe http://code.google.com/p/javadude/wiki/Annotations - Scott

+0

Das ist cool. Obwohl ich mich frage, warum es so etwas in der Sprache nicht gibt. –

0

Ja von oop ist seine die Überlastung, die für die Verwendung von Standard-Parametern um die einzige Möglichkeit ist, in Java. Aber hier ist der Hack für dich. Wenn Sie Überladung verwenden und Standardparameter haben möchten.Dann werden Sie am Ende

public void methodA(A arg1) { } 
public void methodA(B arg2,) { } 
public void methodA(C arg3) { } 
public void methodA(A arg1, B arg2) { } 
public void methodA(A arg1, C arg3) { } 
public void methodA(B arg2, C arg3) { } 
public void methodA(A arg1, B arg2, C arg3) { } 

Aber durch die Verwendung varargs

public class DefaultValue 
{ 
public static void main(String[] args) 
    { 
     defaultParameter(); 
     defaultParameter(true); 
    } 

    public static void defaultParameter(Boolean …gender) 
    { 
     boolean genderBoolean = false; // It is the default value you want to give 
     if(1 == gender.length) 
     { 
      genderBoolean = gender[0]; // Overrided Value 
     } 
     System.out.println(genderBoolean); 
} 
} 

Der obige Code Ausgang

false 
true 

Weitere simliar Beispiele und Erklärungen Besuch java-default-parameter-values

Verwandte Themen