2009-03-06 13 views
2

Je suis assez nouveau à Java et de Python et de PHP, je suis habitué aux valeurs par défaut pour les paramètres de fonction.La surcharge est-elle vraiment le seul moyen d'obtenir des valeurs par défaut pour les paramètres de méthode en Java?

J'ai donc l'habitude d'écrire des méthodes conçues pour être appelées à partir de situations légèrement différentes où vous ne voulez définir que certaines valeurs. Par exemple, dans mon code PHP, ce serait commun où j'ai des méthodes d'usine qui fournissent des instances d'objet avec des propriétés légèrement différentes.

En Java, il me semble que je dois avoir une méthode qui attend tous les paramètres, puis plusieurs variations surchargées qui appellent cette méthode avec certains des paramètres définis par défaut et certains fournis par l'appelant. Ce qui est, bon, d'accord, mais peut parfois m'énerver. Je me souviens que cela m'avait déjà ennuyé dans quelques brèves excursions en C++ et en ActionScript. Maintenant, les développeurs Java plus expérimentés ont-ils un raccourci pour cela?

Il me semble que, techniquement, la réponse à la question est la suivante: «Oui, c'est». J'ai ouvert un message wiki ci-dessous pour collecter les différentes solutions alternatives, merci de contribuer si vous le souhaitez. J'ai trouvé tous ces éléments très utiles comme source d'inspiration et comme exemples d'apprentissage pour des constructions Java typiques.

Répondre

0

Il semble que, « Oui, il est », à l'exception:

Des effets similaires pourraient être obtenus avec varargs comme suggéré par Paul Whelan ou en définissant un type supplémentaire portant les paramètres que les champs avec les valeurs par défaut appropriées comme suggéré par Jon Skeet. Boris Pavlović ajoute que son type pourrait être une classe interne statique pour garder les choses proprement au bon endroit.

Moins (Notez que toute cette question ne porte pas sur des conséquences graves, à peu près quelques réglages pratiques):

VarArgs semble le plus approprié pour faire passer une liste de longueur variable des valeurs qui ont une forme très similaire et la signification essentiellement équivalent , comme une liste de noms. Si elle est utilisée dans le but indiqué dans la question, la méthode devrait effectuer divers contrôles sur la liste afin de l'interpréter, ce qui ne semble pas plus, mais moins pratique. Un type spécial portant les paramètres semble très utile si le type résultant peut avoir d'autres utilisations que le simple passage à une méthode particulière, ou lorsqu'il s'agit d'un ensemble de paramètres plus complexe. S'il y a 2-4 paramètres et que certains peuvent avoir des valeurs par défaut, il semble toujours un peu plus pratique de surcharger, mais cela peut être une question de goût personnel.

3

voir varargs

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

(URL Mise à jour, ce commentaire a ajouté que stackoverflow nécessite> 30 caractères)

+1

Semble comme abus de la fonctionnalité varargs pour moi. – erikkallen

+0

+1 au commentaire de erikkallen. –

+0

Je pense que les varargs sont bons si les arguments varient en nombre mais tous signifient la même chose, comme avec la liste des noms dans ces exemples. Si les arguments signifient quelque chose de différent, vous devrez bientôt mettre en place tant de vérifications que c'est en fait plus propre et plus facile à surcharger. Droite? –

7

Une autre option est une variation sur le modèle de constructeur - vous avez un type qui représente tous les paramètres, construisez une instance de ce type (par défaut), définissez les propriétés souhaitées, puis passez le résultat dans la méthode d'origine ou ajoutez une méthode dans le "type de paramètre" pour appeler la méthode à votre place.

Vous pouvez le voir en action dans les bibliothèques standard, avec les classes ProcessBuilder et Process.

+0

Ouais, cela pourrait être bon pour certaines situations, je le garderai à l'esprit. Cependant, si je me retrouve avec un type qui n'est utile que comme argument pour une seule méthode, je pense que c'est un peu trop gênant. Je vais m'en tenir à la surcharge pour ceux-là. –

+0

@Hanno Fietz vous pouvez déclarer le type comme classe interne statique dans l'objet où la méthode a été déclarée. N'hésitez pas à créer des types. Ils sont gratuits en Java :) –

+0

Bon indice aussi, Boris. Merci. –

0

Tant que vous codez d'une manière OO, vous ne manquerez pas les valeurs par défaut en Java. Les arguments par défaut sont utiles uniquement dans le style de codage procédural.

Dans OO, au lieu de passer l'état à travers les méthodes/procédures, l'état est déjà dans l'objet que vous appelez, ou les objets que vous transmettez en tant que paramètres. La plupart du temps, vous n'avez pas besoin de plus de 1 ou 2 paramètres dans vos méthodes.

Si vous voulez configurer votre objet avant de l'utiliser, vous devez le construire avec un constructeur simple, et ensuite appeler différents setters. Cela rend le code beaucoup plus lisible (parce que vous voyez les noms de setter), comparé à l'appel d'un constructeur ayant de nombreux arguments. Et dans le cas où un nouvel attribut vient plus tard, vous pouvez ajouter à votre objet sans avoir à modifier vos méthodes d'usine existantes.

1

Il peut être très difficile d'essayer de traduire votre processus de conversion d'une langue à l'autre. Vous pouvez, comme d'autres l'ont souligné, faire quelques efforts pour obtenir ce que vous voulez ... mais plus tôt vous «accepterez» la façon dont Java est conçu pour fonctionner, mieux vous serez quand vous travaillerez en Java.

J'ai dû faire quelques trucs de PHP ... m'ennuyait sans fin que je ne pouvais pas l'obtenir pour faire ce que je voulais ... donc ça va dans les deux sens.

Le plus grand obstacle que vous allez rencontrer est probablement le typage statique. Il y a des choses que vous pouvez essayer de faire pour contourner le problème, mais à la fin, ce sera un très gros bidouillage.

Dans les débuts de C++, les gens essayaient de convaincre C++ de se comporter comme Smalltalk ... ne fonctionnait pas très bien. Au début, si les gens de Java essayaient de prendre leurs connaissances en C++ et de les utiliser en Java ... cela ne fonctionnait pas très bien (ce qui est doublement frustrant car les langages sont très similaires en surface).

Mon conseil, pour votre codage Java apprendre à programmer comme un développeur Java plutôt que d'un développeur PHP.

Pour votre problème immédiat, est-il possible que vous deviez vraiment renvoyer des classes différentes de l'usine au lieu de créer le même type d'objet avec différentes variables définies?

+0

+1 pour le dernier commentaire –

+0

"Mon conseil, pour votre codage Java apprendre à programmer comme un développeur Java plutôt que d'un développeur PHP." - +1 pour ça. On dirait que le focus est trop sur les fonctions et les paramètres transmis plutôt que sur les objets et l'état interne. – duffymo

+0

Ne vous méprenez pas sur ce point, je ne suis pas dérangé par les différents concepts dans les langues, j'ai soigneusement choisi Java pour ce projet et je suis content de mon choix. Je me demandais surtout si c'était la langue ou un malentendu de mon côté. –

2

Pour rendre cela plus simple, j'ai créé une annotation pour les valeurs par défaut et un processeur d'annotation qui génère une superclasse avec les méthodes surchargées. Par exemple:

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

qui génère (dans un superclasse généré)

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

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

+0

C'est cool. Bien que je me demande pourquoi il n'y a pas déjà quelque chose comme ça dans la langue. –

0

Oui par ce oop sa surcharge qui est le seul moyen pour l'utilisation paramater par défaut en Java. Mais voici le hack pour vous. Si vous utilisez une surcharge et que vous voulez avoir un paramètre par défaut.Ensuite, vous finirez par

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

Mais en utilisant 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); 
} 
} 

La sortie de code ci-dessus sera

false 
true 

Pour des exemples plus simliar et visite d'explication java-default-parameter-values