java - 重载构造函数 - 重载构造器




如何在Java中调用另一个构造函数? (11)

[ 注意:我只想添加一个方面,我在其他答案中没有看到:如何克服()必须位于第一行的要求的限制)。 ]

在Java中,可以通过this()从构造函数中调用同一类的另一个构造函数。 但请注意, this必须在第一行。

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

这必须出现在第一行看起来像一个很大的限制,但你可以通过静态方法构造其他构造函数的参数。 例如:

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;

  }

}

是否有可能从另一个(在同一个类中,而不是从一个子类)调用构造函数? 如果是的话如何? 调用另一个构造函数的最佳方式是什么(如果有几种方法可以这样做)?


我会告诉你一个简单的方法

两种类型的构造函数:

  1. 默认的构造函数
  2. 参数化的构造函数

我将在一个例子中解释

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

在上面的例子中,我展示了3种类型的调用

  1. this()对此的调用必须是构造函数中的第一条语句
  2. 这是名称较少的对象。 这会自动调用默认的构造函数。 3.这将调用参数化的构造函数。

注意: 这必须是构造函数中的第一条语句。


使用this(args) 。 首选模式是从最小的构造函数到最大的构造函数。

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

您也可以使用最近提倡的valueOf或“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;
 }
} 

要调用超类,请使用super(asdf) 。 对super的调用必须是构造函数中的第一个调用,否则您将收到编译器错误。


关键字this可用于从构造函数中调用构造函数,当为某个类编写多个构造函数时,有时需要从另一个构造函数调用另一个构造函数以避免重复代码。

Bellow是一个链接,我解释了有关构造函数和getters()和setters()的其他主题,并且我使用了一个带有两个构造函数的类。 我希望这些解释和例子能帮助你。

Setter方法或构造函数


对的,这是可能的:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

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

要链接到特定的超类构造函数而不是同一个类中的构造函数,请使用super而不是this 。 请注意, 您只能链接到一个构造函数 ,并且它必须是构造函数体中的第一条语句

另请参阅这个相关的问题 ,这是关于C#,但在相同的原则适用。


当我需要从代码内部调用另一个构造函数时(而不是在第一行),我通常使用如下所示的帮助器方法:

class MyClass {
   int field;


   MyClass() {
      init(0);
   } 
   MyClass(int value) {
      if (value<0) {
          init(0);
      } 
      else { 
          init(value);
      }
   }
   void init(int x) {
      field = x;
   }
}

但是大多数情况下,我都会尝试以相反的方式做到这一点,尽可能从第一行的较简单的构造函数中调用更复杂的构造函数。 对于上面的例子

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}

您可以使用“this”关键字从同一个类的另一个构造函数构造函数。 示例 -

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

输出 - 字符串作为arg构造函数..默认构造函数.. int作为arg构造函数..


我知道这个问题有很多例子,但我发现我在这里分享我的想法。 有两种方法链构造函数。 在同一课程中,您可以使用此关键字。 在继承中,您需要使用超级关键字。

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

是的,可以从另一个构造函数调用。 但是有一条规则。 如果从一个构造函数向另一个构造函数调用,那么

新的构造函数调用必须是当前构造函数中的第一条语句

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

所以下面的东西不会起作用。

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

是的,可以使用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);
   }

正如大家已经说过的,你使用this(…) ,这被称为显式构造函数调用

但是,请记住,在这样的显式构造函数调用语句中, 您可能不会引用

  • 任何实例变量
  • 任何实例方法
  • 在此类或任何超类中声明的任何内部类,或
  • this或者
  • super

正如JLS(§8.8.7.1)所述。





constructor