outro - sobrecarga de construtores java




Como faço para chamar um construtor de outro em Java? (12)

É chamado encurtamento de construtor anti-padrão ou encadeamento de construtor. Sim, você pode definitivamente fazer. Vejo muitos exemplos acima e quero acrescentar dizendo que, se você sabe que precisa de apenas dois ou três construtores, tudo bem. Mas se você precisar de mais, por favor, tente usar um padrão de design diferente, como o padrão Builder. Como por exemplo:

 public Omar(){};
 public Omar(a){};
 public Omar(a,b){};
 public Omar(a,b,c){};
 public Omar(a,b,c,d){};
 ...

Você pode precisar de mais. O padrão do construtor seria uma ótima solução nesse caso. Aqui está um artigo, pode ser útil https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e

É possível chamar um construtor de outro (dentro da mesma classe, não de uma subclasse)? Se sim como? E qual poderia ser a melhor maneira de chamar outro construtor (se há várias maneiras de fazer isso)?


A palavra - chave this pode ser usada para chamar um construtor de um construtor, ao escrever vários construtores para uma classe, há momentos em que você gostaria de chamar um construtor de outro para evitar código duplicado.

Abaixo está um link que eu explico outro tópico sobre construtor e getters () e setters () e usei uma classe com dois construtores. Espero que as explicações e exemplos o ajudem.

Métodos ou construtores de setter


Chamando o construtor de outro construtor

class MyConstructorDemo extends ConstructorDemo
{
    MyConstructorDemo()
    {
        this("calling another constructor");
    }
    MyConstructorDemo(String arg)
    {
        System.out.print("This is passed String by another constructor :"+arg);
    }
}

Além disso, você pode chamar o construtor pai usando a chamada super()


Como todos já disseram, você usa this(…) , que é chamado de invocação de construtor explícito .

No entanto, lembre-se de que dentro de tal instrução de invocação de construtor explícito você não pode se referir a

  • quaisquer variáveis ​​de instância ou
  • quaisquer métodos de instância ou
  • quaisquer classes internas declaradas nesta classe ou em qualquer superclasse, ou
  • this ou
  • super

Como afirmado no JLS (§8.8.7.1).


Eu sei que existem muitos exemplos desta questão, mas o que eu encontrei estou colocando aqui para compartilhar minha idéia. Existem duas maneiras de encadear o construtor. Na mesma classe, você pode usar essa palavra-chave. em Herança, você precisa usar super palavra-chave.

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

Existem padrões de projeto que cobrem a necessidade de uma construção complexa - se isso não puder ser feito de forma sucinta, crie um método de fábrica ou uma classe de fábrica.

Com o java mais recente e a adição de lambdas, é fácil criar um construtor que aceite qualquer código de inicialização desejado.

class LambdaInitedClass {

   public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
       init.accept(this);
   }
}

Chame isso com ...

 new LambdaInitedClass(l -> { // init l any way you want });

Sim, é possível chamar um construtor de outro com o uso 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);
   }

Sim, é possível chamar um construtor de outro. Mas há uma regra para isso. Se uma chamada é feita de um construtor para outro, então

essa nova chamada de construtor deve ser a primeira instrução no construtor atual

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

Então, algo como abaixo não funcionará.

public Product(int id, String name, double price) {
    System.out.println("Calling constructor with price");
    this(id,name,price,"DEFAULT");
}

Além disso, no caso de herança, quando o objeto da subclasse é criado, o construtor de superclasse é chamado primeiro.

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

Assim, nesse caso, outra chamada de construtor é declarada primeiro antes de qualquer outra instrução.


Sim, qualquer número de construtores pode estar presente em uma classe e eles podem ser chamados por outro construtor usando this() [Por favor, não confunda this() construtor com this palavra this chave]. this() ou this(args) deve ser a primeira linha no construtor.

Exemplo:

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

Isso é conhecido como sobrecarga de construtor.
Por favor, note que para o construtor, apenas o conceito de sobrecarga é aplicável e não herança ou substituição.


Usando this(args) . O padrão preferido é trabalhar do menor construtor para o maior.

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

Você também pode usar uma abordagem mais recentemente defendida de valueOf ou apenas "of":

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

Para chamar uma superclasse, use super(someValue) . A chamada para super deve ser a primeira chamada no construtor ou você receberá um erro do compilador.


Você pode um construtor de outro construtor da mesma classe usando a palavra-chave "this". Exemplo -

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

Saída - string como construtor arg .. Construtor padrão .. int como construtor arg ..


[ Nota: Eu só quero adicionar um aspecto, que eu não vi nas outras respostas: como superar as limitações do requisito de que this () tem que estar na primeira linha). ]

Em Java, outro construtor da mesma classe pode ser chamado de um construtor através this() . Note, no entanto, que this tem que estar na primeira linha.

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 tenha que aparecer na primeira linha parece uma grande limitação, mas você pode construir os argumentos de outros construtores através de métodos estáticos. Por exemplo:

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;

  }

}






constructor