Est-il possible d'appeler un constructeur à partir d'un autre (dans la même classe, et non à partir d'une sous-classe)? Si oui, comment? Et quel pourrait être le meilleur moyen pour appeler un autre constructeur (s'il y a plusieurs façons de le faire)?
Réponses
Trop de publicités?Oui, il est possible:
public class Foo
{
private int x;
public Foo()
{
this(1);
}
public Foo(int x)
{
this.x = x;
}
}
De la chaîne à un constructeur de la superclasse au lieu d'un dans la même classe, utilisez super
au lieu de this
. Notez que vous pouvez seulement de la chaîne à un seul constructeur, et elle doit être la première instruction dans votre corps du constructeur.
EDIT: Voir aussi cette question connexe, qui est sur C#, mais où les mêmes principes s'appliquent.
À l'aide de this(args)
. Le modèle préféré est de travailler à partir de la plus petite constructeur pour le plus grand.
public class Cons {
public Cons() {
// A no arguments constructor that sends default values to the largest
this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
}
public Cons(int arg1, int arg2) {
// An example of a partial constructor that uses the passed in arguments
// and sends a hidden default value to the largest
this(arg1,arg2, madeUpArg3Value);
}
// Largest constructor that does the work
public Cons(int arg1, int arg2, int arg3) {
this.arg1 = arg1;
this.arg2 = arg2;
this.arg3 = arg3;
}
}
Vous pouvez également utiliser un plus récemment préconisé l'approche de valueOf ou "de":
public class Cons {
public static Cons newCons(int arg1,...) {
// This function is commonly called valueOf, like Integer.valueOf(..)
// More recently called "of", like EnumSet.of(..)
Cons c = new Cons(...);
c.setArg1(....);
return c;
}
}
Pour appeler un super classe, utilisez super(asdf)
. L'appel à super doit être le premier appel dans le constructeur ou, vous obtiendrez une erreur de compilation.
[Note: je tiens juste à ajouter un aspect, dont je n'ai pas vu dans les autres réponses: comment surmonter les limites de l'exigence que cette() doit être sur la première ligne).]
En Java, un autre constructeur de la même classe peut être appelée à partir d'un constructeur par this()
. Notez toutefois que l' this
a être sur la première ligne.
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, 0.0);
}
public MyClass(double argument1, double argument3, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
}
Qu' this
a apparaître sur la première ligne qui ressemble à une grosse limitation, mais vous pouvez construire les arguments des autres constructeurs via des méthodes statiques. Par exemple:
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, getDefaultArg3(argument1, argument2));
}
public MyClass(double argument1, double argument3, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
private static double getDefaultArg3(double argument1, double argument2) {
double argument3 = 0;
// Calculate argument3 here if you like.
return argument3;
}
}
Quand j'ai besoin d'appeler un autre constructeur de l'intérieur le code (pas sur la première ligne), j'ai l'habitude d'utiliser une méthode d'assistance comme ceci:
class MyClass {
int field;
MyClass() {
init(0);
}
MyClass(int value) {
if (value<0) {
init(0);
}
else {
init(value);
}
}
void init(int x) {
field = x;
}
}
Mais le plus souvent j'essaie de le faire dans l'autre sens en appelant à la plus complexe des constructeurs de la plus simple sur la première ligne, dans la mesure du possible. Pour l'exemple ci-dessus
class MyClass {
int field;
MyClass(int value) {
if (value<0)
field = 0;
else
field = value;
}
MyClass() {
this(0);
}
}