constructores - ¿Cómo llamo a un constructor de otro en Java?



ejercicios otra (16)

Dentro de un constructor, puede usar this palabra clave para invocar a otro constructor en la misma clase. Hacerlo se llama invocación explícita de un constructor .

Aquí hay otra clase de rectángulo, con una implementación diferente de la de la sección Objetos.

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

}

Esta clase contiene un conjunto de constructores. Cada constructor inicializa algunas o todas las variables miembro del rectángulo.

¿Es posible llamar a un constructor desde otro (dentro de la misma clase, no desde una subclase)? Si es así, ¿cómo? ¿Y cuál podría ser la mejor manera de llamar a otro constructor (si hay varias maneras de hacerlo)?


La palabra clave que se puede usar para llamar a un constructor desde un constructor, cuando se escriben varios constructores para una clase, hay veces en que le gustaría llamar a un constructor desde otro para evitar el código duplicado.

A continuación hay un enlace en el que explico otro tema sobre constructor y getters () y setters () y usé una clase con dos constructores. Espero que las explicaciones y los ejemplos te ayuden.

Métodos de Setter o constructores.


Como todos ya lo han dicho, usa this(…) , que se llama invocación explícita de constructor .

Sin embargo, tenga en cuenta que dentro de una declaración de invocación de constructor tan explícita no puede hacer referencia a

  • cualquier variable de instancia o
  • cualquier método de instancia o
  • cualquier clase interna declarada en esta clase o cualquier superclase, o
  • this o
  • super

Como se indica en JLS (§8.8.7.1).


Sí, es posible llamar a un constructor desde otro con el uso 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);
   }

Llamando al constructor desde otro constructor

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

También puedes llamar al constructor principal usando super() call


Sí, es posible:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

Para encadenar a un constructor de superclase en particular en lugar de uno en la misma clase, use super lugar de this . Tenga en cuenta que solo puede encadenar a un constructor , y tiene que ser la primera declaración en su cuerpo de constructor .

Vea también esta pregunta relacionada , que trata sobre C # pero donde se aplican los mismos principios.


Te diré una manera fácil

Hay dos tipos de constructores:

  1. Constructor predeterminado
  2. Constructor parametrizado

Voy a explicar en un ejemplo

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

En el ejemplo anterior mostré 3 tipos de llamadas.

  1. Esta () llamada a esto debe ser la primera declaración en el constructor.
  2. Esto es Nombre menos Objeto. esto llama automáticamente al constructor por defecto. 3.Esto llama al constructor parametrizado.

Nota: esta debe ser la primera declaración en el constructor.


Puede usar un constructor de otro constructor de la misma clase usando la palabra clave "this". Ejemplo -

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

Salida - cadena como constructor arg. Constructor por defecto .. int como constructor arg.


Utilizando this(args) . El patrón preferido es trabajar desde el constructor más pequeño hasta el más grande.

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

También puede utilizar un enfoque más reciente de valueOf o simplemente "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 llamar a una súper clase, use super(someValue) . La llamada a super debe ser la primera llamada en el constructor o obtendrá un error del compilador.


Puede llamar a otro constructor a través de la palabra clave this(...) (cuando necesita llamar a un constructor de la misma clase) o la palabra clave super(...) (cuando necesita llamar a un constructor desde una superclase).

Sin embargo, dicha llamada debe ser la primera declaración de su constructor. Para superar esta limitación, usa esta respuesta .


Se llama anti-patrón de constructor telescópico o encadenamiento de constructor. Sí, definitivamente puedes hacerlo. Veo muchos ejemplos arriba y quiero agregar diciendo que si sabe que necesita solo dos o tres constructores, podría estar bien. Pero si necesita más, intente utilizar un patrón de diseño diferente, como el patrón Builder. Como por ejemplo:

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

Es posible que necesite más. Patrón de generador sería una gran solución en este caso. Aquí hay un artículo, podría ser útil https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e


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

Ahora aquí hay un pequeño crédito extra:

public SomeOtherClass extends SomeClass {
    public SomeOtherClass(int number, String someString){
         super(number, someString); //calls public SomeClass(int number, String someString)
    }
    //.... Some other code.
}

Espero que esto ayude.


Sí, es posible llamar a un constructor desde otro. Pero hay una regla para ello. Si se realiza una llamada de un constructor a otro, entonces

esa nueva llamada de constructor debe ser la primera declaración en el constructor actual

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

Por lo tanto, algo como abajo no funcionará.

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

Además, en el caso de la herencia, cuando se crea un objeto de subclase, se llama primero al constructor de la superclase.

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

Por lo tanto, en este caso también se declara primero otra llamada de constructor antes que cualquier otra declaración.


Sé que hay muchos ejemplos de esta pregunta, pero lo que encontré lo estoy poniendo aquí para compartir mi Idea. Hay dos formas de encadenar constructor. En la misma clase puedes usar esta palabra clave. en Herencia, es necesario utilizar súper palabra clave.

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

Sí, cualquier número de constructores puede estar presente en una clase y puede ser llamado por otro constructor usando this() [Por favor, no confunda this() llamada del constructor this() con this palabra clave]. this() o this(args) debe ser la primera línea en el constructor.

Ejemplo:

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

Esto se conoce como sobrecarga del constructor.
Tenga en cuenta que para el constructor, solo se aplica el concepto de sobrecarga y no la herencia o la anulación.


Cuando se construye un objeto escrito en C #, lo que sucede es que los inicializadores se ejecutan en orden de la clase más derivada a la clase base, y luego los constructores se ejecutan en orden de la clase base a la clase más derivada ( consulte el blog de Eric Lippert para obtener más detalles en cuanto a por qué esto es ).

También en .NET, los objetos no cambian el tipo a medida que se construyen, sino que comienzan como el tipo más derivado, con la tabla de métodos para el tipo más derivado. Esto significa que las llamadas a métodos virtuales siempre se ejecutan en el tipo más derivado.

Cuando combina estos dos hechos, queda con el problema de que si realiza una llamada de método virtual en un constructor, y no es el tipo más derivado en su jerarquía de herencia, se llamará en una clase cuyo constructor no haya sido ejecutar, y por lo tanto no puede estar en un estado adecuado para tener ese método llamado.

Este problema, por supuesto, se mitiga si marca su clase como sellada para garantizar que sea el tipo más derivado en la jerarquía de herencia, en cuyo caso es perfectamente seguro llamar al método virtual.





java constructor