Comment appeler un constructeur à partir d'un autre en Java?
est-il possible d'appeler un constructeur d'un autre (dans la même classe, pas d'une sous-classe)? Si oui, comment? Et quelle pourrait être la meilleure façon d'appeler un autre constructeur (s'il y a plusieurs façons de le faire)?
18 réponses
Oui, c'est possible:
public class Foo {
private int x;
public Foo() {
this(1);
}
public Foo(int x) {
this.x = x;
}
}
pour enchaîner à un constructeur de superclasses particulier au lieu d'un constructeur de la même classe, utiliser super
au lieu de this
. Notez que vous pouvez seulement enchaîner à un constructeur , et il doit être la première déclaration dans votre corps de constructeur .
Voir aussi cette question relative à la , ce qui est sur C#, mais où le même principes s'appliquent.
par this(args)
. Le modèle préféré est de travailler du plus petit constructeur au 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 une super classe, utilisez super(someValue)
. L'appel à super doit être le premier appel dans le constructeur ou, vous obtiendrez une erreur de compilation.
[ Remarque: je veux 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é à partir d'un constructeur via this()
. Note toutefois que this
doit ê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 argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
}
Que this
doit apparaître sur la première ligne semble comme une grande limitation, mais vous pouvez construire les arguments d'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 argument2, 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 du code (pas sur la première ligne), j'utilise habituellement une méthode d'aide comme celle-ci:
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 les constructeurs les plus complexes à partir des plus simples 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);
}
}
dans un constructeur, vous pouvez utiliser le mot-clé this
pour invoquer un autre constructeur dans la même classe. Cela s'appelle une invocation explicite du constructeur .
Voici une autre classe de Rectangle, avec une implémentation différente de celle de la section Objets.
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(1, 1);
}
public Rectangle(int width, int height) {
this( 0,0,width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
Cette classe contient un ensemble de constructeurs. Chaque constructeur initialise une partie ou la totalité des variables membres du rectangle.
comme tout le monde l'a déjà dit, vous utilisez this(…)
, qui est appelé un invocation explicite du constructeur .
Cependant, gardez à l'esprit que dans une telle déclaration d'invocation explicite du constructeur vous ne pouvez pas vous référer à
- tout variables d'instance ou
- tout les méthodes d'instance ou
- toute classe classes intérieures déclarée dans cette classe ou dans toute superclasse, ou
-
this
ou -
super
.
comme indiqué dans JLS (§8.8.7.1).
je vais vous dire un moyen facile
il y a deux types de constructeurs:
- constructeur par Défaut
- constructeur Paramétré
je vais expliquer dans un exemple
class ConstructorDemo
{
ConstructorDemo()//Default Constructor
{
System.out.println("D.constructor ");
}
ConstructorDemo(int k)//Parameterized constructor
{
this();//-------------(1)
System.out.println("P.Constructor ="+k);
}
public static void main(String[] args)
{
//this(); error because "must be first statement in constructor
new ConstructorDemo();//-------(2)
ConstructorDemo g=new ConstructorDemo(3);---(3)
}
}
dans l'exemple ci-dessus, j'ai montré 3 types d'appel
- ce() appeler cela doit être la première instruction du constructeur
- ici Nom Sans objet. cela appelle automatiquement le constructeur par défaut. 3.Cela appelle le constructeur Paramétrisé.
Note: ce doit être la première instruction du constructeur.
Oui, n'importe quel nombre de constructeurs peut être présent dans une classe et ils peuvent être appelés par un autre constructeur en utilisant this()
[s'il vous plaît ne pas confondre this()
appel constructeur avec this
mot-clé]. this()
ou this(args)
doit être la première ligne du constructeur.
exemple:
Class Test {
Test() {
this(10); // calls the constructor with integer args, Test(int a)
}
Test(int a) {
this(10.5); // call the constructor with double arg, Test(double a)
}
Test(double a) {
System.out.println("I am a double arg constructor");
}
}
c'est ce qu'on appelle la surcharge du constructeur.
Veuillez noter que pour le constructeur, seulement la surcharge le concept est applicable et non héréditaire ou supérieur.
Oui il est possible d'appeler un constructeur d'un autre. Mais il y a une règle. Si un appel est fait d'un constructeur à un autre, alors
cet appel de nouveau constructeur doit être la première déclaration dans le constructeur actuel
public class Product {
private int productId;
private String productName;
private double productPrice;
private String category;
public Product(int id, String name) {
this(id,name,1.0);
}
public Product(int id, String name, double price) {
this(id,name,price,"DEFAULT");
}
public Product(int id,String name,double price, String category){
this.productId=id;
this.productName=name;
this.productPrice=price;
this.category=category;
}
}
donc, quelque chose comme ci-dessous ne fonctionnera pas.
public Product(int id, String name, double price) {
System.out.println("Calling constructor with price");
this(id,name,price,"DEFAULT");
}
également, dans le cas d'héritage, lorsque la objet est créé, le constructeur super class est d'abord appelé.
public class SuperClass {
public SuperClass() {
System.out.println("Inside super class constructor");
}
}
public class SubClass extends SuperClass {
public SubClass () {
//Even if we do not add, Java adds the call to super class's constructor like
// super();
System.out.println("Inside sub class constructor");
}
}
ainsi, dans ce cas aussi un autre appel du constructeur est d'abord déclaré avant toute autre déclaration.
vous pouvez un constructeur d'un autre constructeur de la même classe en utilisant" ce " mot-clé. Exemple -
class This1
{
This1()
{
this("Hello");
System.out.println("Default constructor..");
}
This1(int a)
{
this();
System.out.println("int as arg constructor..");
}
This1(String s)
{
System.out.println("string as arg constructor..");
}
public static void main(String args[])
{
new This1(100);
}
}
sortie - string arg constructeur.. Constructeur par défaut.. int arg constructeur..
appelant le constructeur d'un autre constructeur
class MyConstructorDemo extends ConstructorDemo
{
MyConstructorDemo()
{
this("calling another constructor");
}
MyConstructorDemo(String arg)
{
System.out.print("This is passed String by another constructor :"+arg);
}
}
vous pouvez aussi appeler le constructeur parent en utilisant super()
call
Oui il est possible d'appeler un constructeur de l'autre avec l'utilisation de this()
class Example{
private int a = 1;
Example(){
this(5); //here another constructor called based on constructor argument
System.out.println("number a is "+a);
}
Example(int b){
System.out.println("number b is "+b);
}
le mot-clé ce peut être utilisé pour appeler un constructeur à partir d'un constructeur, lorsque vous écrivez plusieurs constructeurs pour une classe, Il ya des moments où vous souhaitez appeler un constructeur à partir d'un autre pour éviter le code dupliqué.
ci-dessous est un lien que j'explique autre sujet sur le constructeur et getters() et setters() et j'ai utilisé une classe avec deux constructeurs. J'espère que les explications et les exemples vous aideront.
il y a des modèles de conception qui couvrent le besoin de construction complexe - si cela ne peut pas être fait de façon succincte, créer une méthode d'usine ou une classe d'usine.
avec le dernier java et l'ajout de lambdas, il est facile de créer un constructeur qui peut accepter n'importe quel code d'initialisation que vous désirez.
class LambdaInitedClass {
public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
init.accept(this);
}
}
appelez-le avec...
new LambdaInitedClass(l -> { // init l any way you want });
Assez simple
public class SomeClass{
int number;
String someString;
public SomeClass(){
number = 0;
}
public SomeClass(int number){
this(); //set the class to 0
this.setNumber(number);
}
public SomeClass(int number, String someString){
this(number); //call public SomeClass( int number )
}
public void setNumber(int number){
this.number = number;
}
public void setString(String someString){
this.someString = someString;
}
//.... add some accessors
}
voici maintenant un petit crédit supplémentaire:
public SomeOtherClass extends SomeClass {
public SomeOtherClass(int number, String someString){
super(number, someString); //calls public SomeClass(int number, String someString)
}
//.... Some other code.
}
Espérons que cette aide.
je sais qu'il y a tant d'exemples de cette question mais ce que j'ai trouvé je le mets ici pour partager mon idée. il y a deux façons d'enchaîner le constructeur. Dans la Même classe, vous pouvez utiliser ce mot clé. dans l'Héritage, vous devez utiliser le mot clé super.
import java.util.*;
import java.lang.*;
class Test
{
public static void main(String args[])
{
Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
// You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
System.out.println("------------------------------");
Cat c = new Cat();
Cat caty = new Cat("10");
System.out.println("------------------------------");
// Self s = new Self();
Self ss = new Self("self");
}
}
class Animal
{
String i;
public Animal()
{
i = "10";
System.out.println("Animal Constructor :" +i);
}
public Animal(String h)
{
i = "20";
System.out.println("Animal Constructor Habit :"+ i);
}
}
class Dog extends Animal
{
public Dog()
{
System.out.println("Dog Constructor");
}
public Dog(String h)
{
System.out.println("Dog Constructor with habit");
}
}
class Cat extends Animal
{
public Cat()
{
System.out.println("Cat Constructor");
}
public Cat(String i)
{
super(i); // Calling Super Class Paremetrize Constructor.
System.out.println("Cat Constructor with habit");
}
}
class Self
{
public Self()
{
System.out.println("Self Constructor");
}
public Self(String h)
{
this(); // Explicitly calling 0 args constructor.
System.out.println("Slef Constructor with value");
}
}
vous pouvez appeler un autre constructeur via le this(...)
mot-clé (quand vous devez appeler un constructeur de la même classe) ou le super(...)
mot-clé
(lorsque vous devez appeler un constructeur à partir d'une superclasse).
cependant, un tel appel doit être le premier déclaration de votre constructeur. surmonter cette limitation, l'utilisation de cette réponse .
il est appelé télescopique constructeur anti-modèle ou enchaînement constructeur. Oui, vous pouvez certainement le faire. Je vois beaucoup d'exemples ci-dessus et je tiens à ajouter que si vous savez que vous avez besoin de seulement deux ou trois constructeurs, il pourrait être ok. Mais si vous avez besoin de plus, s'il vous plaît essayer d'utiliser un modèle de conception différente comme Builder pattern. Comme par exemple:
public Omar(){};
public Omar(a){};
public Omar(a,b){};
public Omar(a,b,c){};
public Omar(a,b,c,d){};
...
vous pourriez avoir besoin de plus. Modèle de constructeur serait une excellente solution dans ce cas. Voici un article, il peut être utile https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e