Methoden Parameter optionalisieren möglich? - Wie?

Assembler

Mitglied
Also ich bin gerade dabei ein Schachspiel zu programmieren und mir würde es leichter fallen, wenn man parameter bloß gegebenenfalls angeben muss.
Die Frage also: Kann man Parameter weglassen? - Wenn ja, wie?
Auf Google habe ich nichts gefunden... Eventuell habe ich meine Frage zu komplex formuliert.

Ich danke Euch für Eure Antworten!

liebe Grüße
Assembler:rtfm:
 
Ich habe es jetzt mit einer Prüfung ob eine Null-referenz besteht, gemacht.
==> Wenn der Parameter keine Null-referenz aufweist, dann führe normal aus, andernfalls lasse den Parameter aus(ersetze ihn);

liebe Grüße
Assembler:rtfm:
 
Hey Assembler,

Dafür gibt es die sogenannte ... Notation. Dazu gibst du in der Parameterliste einfach den Darentypen an, den du gegebenenfalls übergeben möchtest und schreibst 3 Punkte dahinter, dann den Namen.
Beispiel:
void test(int... ints)

Damit wird zu Laufzeit ein Array erzeugt. Der Vorteil ist aber, du kannst mehrere Argumente oder gar keinen übergeben.

Die andere Möglichkeit ist einfach die Methode zu überladen 🙂

Grüße Coco07
 
Ich finde das sehr unschön und würde es nur im Notfall benutzen. Sprich wenn ich wirklich eine unbekannte Anzahl Parameter habe. Das kommt aber extrem selten, bis fast gar nicht vor.

Sag uns doch mal dein konkretes Beispiel wofür du es benutzen willst. Ich wette da gibt es schönere Wege.

Gruß

Claus
 
Rückfrage: Wenn ich die Notation anwende, kann ich sie nicht mehrmals hintereinander machen...
Muss ich dann den Array nutzen, der angefertigt wurde, um die Werte zu bekommen? Muss ich dann auch einen Array übergeben???

Liebe Grüße
Assembler:rtfm:
 
Ja, es besteht eine schönere Lösung, allerdings ist dort viel mehr Schreibarbeit. Ich benutze das um das Feld zu erstellen. Es soll nämlich referenzen in alle Himmelsrichtungen besitzen und dafür möchte ich mir nicht so viel Schreibarbeit machen. Für mich ist es so auch übersichtlicher. Das Feld wird dann rekursiv aufgebaut. Ich möchte keine Beispiele posten, da das meine Facharbeit ist, welche bis Montag fertig sein muss. Mein Lehrer denkt, ich wäre schlecht und deswegen versuche ich dort auch teilweise ausgefallene, aber strukturell zweckmäßige Vorgehensweisen zu verwenden. Bin in der 1. Qualifikationsphase 😉
 
Rückfrage: Wenn ich die Notation anwende, kann ich sie nicht mehrmals hintereinander machen...
Geht schon.

Muss ich dann den Array nutzen, der angefertigt wurde, um die Werte zu bekommen
ja, wie willst du sonst auf die Argumente zugreifen? Du weisst ja innerhalb der Methode nie, wieviel Argumentedu bekommst...

Muss ich dann auch einen Array übergeben???
Du kannst ein Array übergeben, oder auch die Argumente mit "," getrennt:
z.B.
Java:
public static void main(String[] args) {
    test(1,2,3);        
    test(1,2,3,4,5,6);
    int [] zahlen = new int [] {1,2,3,4,5,6};
    test(zahlen);
}
public static void test(int ... ints) {
   for (int i : ints) {
      System.out.println(i);
   }
}
 

Der TO wollte wissen ob so etwas möglich wäre:
Java:
public static void test(int... ints, String... strings) {
   ....
}

Das ist leider nicht möglich. Auch ist diese Notation nicht für "optionale" Parameter gedacht.

@TO:
Bau dir aus deinen Werten doch einfach ein Objekt zusammen und übergib dieses.
Du kannst beim Befüllen des Objektes (setter Methoden) schon Werte validieren usw., du hast immer einen Parameter und ersparst dir die x Prüfungen in der eigentlichen Methode (wurde in die Objekt Klasse verschoben)
 
Assembler@

Habe mir gerade meinen Post erneut durchgelesen und musste auch etwas schmunzeln 😳
Ich wollte eigentlich nicht ausdrücken, dass diese Notation genau für solche Fälle ist. Sie ist eben für Fälle, in denen man nicht genau weiß, wie viele Argumente man übergeben möchte. Der Vorteil ist eben wirklich, dass man nicht extra einen Array deklarieren, erzeugen und befüllen muss sondern diese Dinge im "Hintergrund" automatisch passieren.
Inwiefern das jetzt deinem Design entspricht, ist natürlich deine Sache. Alternativ kannst du deine Methode überladen oder wie José bereits schrieb, einen eigenen Datentypen erstellen und dort deine Daten "reinpacken" und evtl. über eine List übergeben 🙂

grüße coco07!
 
@coco97 &@Joose Danke euch, habe es auch schon so gemacht ^^ Ich wünschte mir echt, dass solche Antworten früher kommen.... Leider bin ich zu ungeduldig um dafür paar Stunden zu warten >_>

Liebe Grüße
Kampfsorb
 
Um mal den ersten, wirklich fragebezogenen Post hier zu machen:

In Java gibt es keine optionalen Parameter. In z.B. PHP kannst du folgendes schreiben:

PHP:
public function doSomething($arg1, $arg2, $arg3 = "foo", $arg4 = null)
{
    // code...
    if ($arg4 == null) // ...
    else //...
}

In Java musst du die Methode überladen:
Java:
public void doSomething(int arg1, int arg2)
{
    doSomething(arg1, arg2, "foo");
}

public void doSomething(int arg1, int arg2, String arg3)
{
    doSomething(arg1, arg2, arg3, null);
}

public void doSomething(int arg1, int arg2, String arg3, String arg4)
{
    // code...
    if (arg4 == null) // ...
    else // ...
}

Ja, das ist mehr schreibarbeit. Aber so macht man es in Java. Und wenn du das mit Varargs (die ... Notation) machst, kommst du früher oder Später in Teufels Küche, glaub mir.
 
@Tobse
Das würde ich so nicht sagen. Es gibt durchaus Methoden, wo die VarArgs besonders nützlich sind. Besonders bei Methoden, welche ich ansonsten 10 mal überladen müsste, wäre das von Vorteil um die Übersichtlichkeit und Wartbarkeit zu behalten. Allerdings ist dann auch die Frage, ob kein fehlerhaftes Design vorliegt. Trotzdem gibt es diese Situationen 😉

grüße coco07!
 
@Tobse
Das würde ich so nicht sagen. Es gibt durchaus Methoden, wo die VarArgs besonders nützlich sind. Besonders bei Methoden, welche ich ansonsten 10 mal überladen müsste, wäre das von Vorteil um die Übersichtlichkeit und Wartbarkeit zu behalten. Allerdings ist dann auch die Frage, ob kein fehlerhaftes Design vorliegt. Trotzdem gibt es diese Situationen 😉

grüße coco07!

Sorry, aber das ist Quark, genau dafür sind Varargs nicht (!) gedacht.

Wenn du als Aufrufer die Parameter kennst dann solltest du auch eine Methode mit konkreten Parametern aufrufen.

Varargs sind eher syntactic-sugar aber sollten imho immer typisiert sein. Ein Object-Vararg ist im Normalfall nicht sinnvoll.

Oder willst du solchen Code schreiben:

Code:
void foo(Object...some) {
   String name, int age, Date dateOfBirth;

   if(some[0] instanceof String) name = (String) some[0];
   ...
}

void bar() {
   foo("Hans", 18, null);
}

*schauder*
 
Zuletzt bearbeitet:
KSG9|sebastian@
Wer sagt, dass der Datentyp Object sein muss? Habe ich hier nirgends geschrieben oder gelesen, denke da hast du dich vertan 😉
Beispiel:
Java:
KSG9|public void add(int paramInt1, int paramInt2){}
	public void add(int paramInt1, int paramInt2, int paramInt3){}
	public void add(int paramInt1, int paramInt2, int paramInt4, int paramInt5){}
	public void add(int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5){}
	public void add(int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, int paramInt6){}
	public void add(int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, int paramInt6, int paramInt7){}
	public void add(int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, int paramInt6, int paramInt7, int paramInt8){}
	public void add(int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, int paramInt6, int paramInt7, int paramInt8, int paramInt9){}
	public void add(int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, int paramInt6, int paramInt7, int paramInt8, int paramInt9, int paramInt10){}

Dann doch lieber mit einer Methode:
Java:
public void add(int paramtInt1, int paramInt2, int... paramIntArray)

Da diese Notation aus der Sprache C kommt, kann ich nicht sagen, wofür das in C genutzt wird.
Aber wenn ich Veränderungen an der Methode vornehmen soll, dann doch lieber bei einer und nicht bei 10.

Übrigens möchte ich die Methode add noch mit 44, 55, 66, 77, 88, 99 und 100 Argumenten aufrufen können 😉

Warum sollte man damit in Teufels Küche kommen? Wenn du mir einen Grund geben könntest, dies nicht so zu tun, würde ich das ja verstehen aber nur weil es Konvention ist ? Lächerlich

grüße coco07!
 
Zuletzt bearbeitet:
Auch wenn ich mich wiederhole: Das ist Quatsch!

1. Wenn du solche Methoden schreibst (20x überladen mit 30 gleichen Parametern) dann ist dein Softwaredesign Schrott
2. Wer soll denn kapieren was du in den Varargs erwartest? Als Aufrufer hast du dadurch keine Ahnung was wie wo erwartet wird

Eine Methode
Code:
void foo(int alter, int anzahlGeschwister, int anzahlKinder, int verheiratetSeit) {..}
kann ich sinnvoll aufrufen und weiß zu jeder Zeit was der Aufruf bedeutet.

Baut man die Methode mit Varargs kapiert kein Mensch mehr (nichtmal der Entwickler einen Tag später) was welcher Parameter bedeutet.
Des Weiteren hast du keine Chance das Ding vernünftig z.B. zu Annotieren (Validation-Bindings o.ä.) und noch zig weitere Dinge.

Den sinnvollen Einsatz von Varargs sieht man z.B. in der der Klasse java.util.Arrays.asList(...)

Varargs sind sehr gut geeignet um vorhandene Methoden mit einem Array-Parameter "schöner" aufrufbar zu machen.

Andere Möglichkeit ist z.B. folgende

Code:
void createPerson(String firstName, String lastName, Address...addresses) {  }

Der Name der Funktion sagt eindeutig was sie tut und an der Methodensignatur kann der Aufrufer sehen: "Aha, da wird eine Person mit optionalen Adressen angelegt".

Bei einer Methode

Code:
void foo(double a, short c, int...x)

denke ich mir als Aufrufer: "Aha, ich muss meinen Entwicklerkollegen verhauen weil er wieder unlesbaren, ausdruckslosen Müll produziert"
 
Zuletzt bearbeitet:
Also irgendwie verstehe ich deine Ansätze nicht. Du weißt aber schon, dass mein oben geposteter Code nur ein Beispiel ist oder? Niemals würde ich diesen Code so releasen, die Namen waren einfach nur aus Faulheit so gewählt und die Situation war frei erfunden. In der Tat ist dein Beispiel mit den multiplen Adressen genau der gleiche Fall wie meiner mit den mehreren Summanden. Warum also ist mein Beispiel Quark und deiner nicht?

grüße coco07!
 
coco07 hat gesagt.:
Also irgendwie verstehe ich deine Ansätze nicht.

Genau da liegt das Problem 😛

Folgendes Beispiel: Welche Methodensigantur verstehst du besser?

Java:
public int summiere(int... summanden);

oder

Java:
public int summiere(int... x);

Und ja, für eine Methode, welche eine Summe bildet oder das minimum bzw maximum findet, den durchschnitt berechnet oder oder oder sind Varargs DAS mittel der Wahl.

ABER:
Wenn eine Methode nur für eine definierte Menge an Argumenten gültig ist (oder noch abstrakter ausgedrück: nur für eine bestimmte Menge an Parameter-Mengen definiert ist), dann sind Varargs der Tod.

Noch ein Beispiel:

Java:
/**
 * Berechnet die Fläche des Quadrats mit der Kantenlänge a.
 * @param a Kantenlänge des Quadrats
 * @return Die Fläche des Quadrats mit der Kantenlänge a
 */
public int rechteckFlaeche(int a)
{
    return rechteckFlaeche(a, a);
}

/**
 * Berechnet die Fläche des Rechtecks mit den Kantenlängen a und b.
 * @param a Erste Kantenlänge des Rechtecks
 * @param b Zweite Kantenlänge des Rechtecks
 * @return Die Fläche des Rechtecks mit den Kantenlängen a und b.
 */
public int rechteckFlaeche(int a, int b)
{
    return a * b;
}

im Vergleich mit

Java:
/**
 * Berechnet die Kantenlänge des Rechtecks mit den gegebenen Kantenlängen.
 * @param x Die Kantenlängen des Rechtecks. Muss aus einem oder zwei elementen bestehen;
 * ist nur eines gegeben wird die fäche des Quadrats berechnet, sind zwei gegeben die Fläche
 * des Rechtecks mit den beiden Kantenlängen.
 * @return Die Kantenlängen des Rechtecks.
 * @throws InvalidArgumentException Falls x weniger als ein Element hat.
 * @throws InvalidArgumentException Falls x mehr als 2 Elemente hat.
 */
public int rechteckFlaeche(int... x)
{
    if (x.length < 1) // throw ...
    if (x.length > 2) // throw ...
    return x.length == 1? return x[0] * x[0] : x[0] * x[1];
}

Diese Methoden sind schon besser kommentiert als es die meissten tun. Und dennoch brauchst du nach nichtmal einem Arbeitstag mehr als doppelt so lange, die 2. Variante zu verstehen als du für die erste brauchst.
Mal ganz zu schweigen davon, dass der Compiler exakt 0 Chance hat, zu Prüfen, ob du die zweite Variante richtig aufrufst. Das ist dann gefolgt von bösen RuntimeExceptions und - in letzter Konsequenz - unzufriedenen Usern/Kunden. Und genau das - unzufriedene User - ist der Tod jeder Software.

P.S.: Ja, fast jeder Software. Software mit (nahezu) Monopolstellung ist da mal ausgeschlossen *ähem* M$ * ähem*.
 
Zuletzt bearbeitet:

Zurück
Oben