Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,如何从一个构造函数调用另一个构造函数?_Java_Constructor - Fatal编程技术网

在Java中,如何从一个构造函数调用另一个构造函数?

在Java中,如何从一个构造函数调用另一个构造函数?,java,constructor,Java,Constructor,是否可以从另一个(在同一个类中,而不是从子类)调用构造函数?如果是,怎么做?调用另一个构造函数的最佳方法是什么(如果有几种方法),是的,可能是: public class Foo { private int x; public Foo() { this(1); } public Foo(int x) { this.x = x; } } 要链接到特定的超类构造函数而不是同一类中的超类构造函数,请使用super而不是thi

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

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}
要链接到特定的超类构造函数而不是同一类中的超类构造函数,请使用
super
而不是
this
。请注意,只能链接到一个构造函数,它必须是构造函数体中的第一条语句

另请参见,这是关于C的,但适用相同的原则。

使用
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”:

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

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

在Java中,可以通过
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;
  }
}
this
必须出现在第一行,这看起来是一个很大的限制,但是您可以通过静态方法构造其他构造函数的参数。例如:

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;

  }

}
public class Animal {
    private int animalType;

    public Animal() {
        this(1); //here this(1) internally make call to Animal(1);
    }

    public Animal(int animalType) {
        this.animalType = animalType;
    }
}

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

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字段;
MyClass(){
init(0);
} 
MyClass(int值){

如果(value)如大家所说,您使用
这个(…)
,它被称为显式构造函数调用

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

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

如JLS(§8.8.7.1)所述,

在构造函数中,可以使用
this
关键字调用同一类中的另一个构造函数。这样做称为显式构造函数调用

这里是另一个矩形类,其实现与对象部分中的实现不同

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

}

此类包含一组构造函数。每个构造函数初始化矩形的部分或全部成员变量。

您可以使用“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);
    }
}
输出- 字符串作为参数构造函数。。 默认构造函数。。
int作为arg构造函数。

是可以使用
this()从一个构造函数调用另一个构造函数。


是的,一个类中可以存在任意数量的构造函数,其他构造函数可以使用
this()
[请不要将
this()
构造函数调用与
this
关键字混淆]。
this()
this(args)
应该是构造函数中的第一行

例如:

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");
    }
}
这称为构造函数重载。

请注意,对于构造函数,只有重载概念才适用,而不是继承或重写。

我将告诉您一个简单的方法

有两种类型的施工人员:

  • 默认构造函数
  • 参数化构造函数
  • 我将用一个例子来解释

    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种类型的调用

  • 对this的this()调用必须是构造函数中的第一条语句
  • 这是无名称对象。它会自动调用默认构造函数。 3.这将调用参数化构造函数
  • 注:
    这必须是构造函数中的第一条语句。

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

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

    class MyConstructorDemo extends ConstructorDemo
    {
        MyConstructorDemo()
        {
            this("calling another constructor");
        }
        MyConstructorDemo(String arg)
        {
            System.out.print("This is passed String by another constructor :"+arg);
        }
    }
    
    所以,像下面这样的方法是行不通的

    public Product(int id, String name, double price) {
        System.out.println("Calling constructor with price");
        this(id,name,price,"DEFAULT");
    }
    
    此外,在继承的情况下,当创建子类的对象时,首先调用超类构造函数

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

    因此,在这种情况下,在任何其他语句之前首先声明另一个构造函数调用。

    从另一个构造函数调用构造函数

    class MyConstructorDemo extends ConstructorDemo
    {
        MyConstructorDemo()
        {
            this("calling another constructor");
        }
        MyConstructorDemo(String arg)
        {
            System.out.print("This is passed String by another constructor :"+arg);
        }
    }
    
    此外,您还可以使用
    super()
    call

    关键字调用父构造函数。此可用于从构造函数调用构造函数。当为一个类编写多个构造函数时,有时您希望从另一个构造函数调用一个构造函数,以避免重复代码

    下面是一个链接,我解释了关于构造函数和getters()和setters()的其他主题,我使用了一个包含两个构造函数的类。我希望这些解释和示例对您有所帮助


    有一些设计模式可以满足复杂构造的需要-如果不能简洁地完成,请创建一个工厂方法或工厂类

    通过最新的java和lambdas的添加,很容易创建一个构造函数,它可以接受您想要的任何初始化代码

    class LambdaInitedClass {
    
       public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
           init.accept(this);
       }
    }
    
    很简单

    public class SomeClass{
    
        private int number;
        private String someString;
    
        public SomeClass(){
            number = 0;
            someString = new String();
        }
    
        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 )
            this.setString(someString);
        }
    
        public void setNumber(int number){
            this.number = number;
        }
        public void setString(String someString){
            this.someString = someString;
        }
        //.... add some accessors
    }
    
    现在这里有一些额外的小额信贷:

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

    希望这能有所帮助。

    我知道这个问题有很多例子,但我在这里发现的东西是为了分享我的想法。有两种方法可以链接构造函数。在同一个类中,您可以使用此关键字。在继承中,您需要使用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");
            }
        }
    

    它被称为伸缩构造函数反模式或构造函数链接。是的,你肯定能做到。我在上面看到很多例子,我想补充一点,如果你知道你只需要tw
    public class SomeClass{
    
        private int number;
        private String someString;
    
        public SomeClass(){
            number = 0;
            someString = new String();
        }
    
        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 )
            this.setString(someString);
        }
    
        public void setNumber(int number){
            this.number = number;
        }
        public void setString(String someString){
            this.someString = someString;
        }
        //.... add some accessors
    }
    
    public SomeOtherClass extends SomeClass {
        public SomeOtherClass(int number, String someString){
             super(number, someString); //calls public SomeClass(int number, String someString)
        }
        //.... Some other code.
    }
    
        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 Omar(){};
     public Omar(a){};
     public Omar(a,b){};
     public Omar(a,b,c){};
     public Omar(a,b,c,d){};
     ...
    
    { 
      System.out.println("this is shared constructor code executed before the constructor");
      field1 = 3;
    }
    
        class User {
            private long id;
            private String username;
            private int imageRes;
    
        public User() {
            init(defaultID,defaultUsername,defaultRes);
        }
        public User(String username) {
            init(defaultID,username, defaultRes());
        }
    
        public User(String username, int imageRes) {
            init(defaultID,username, imageRes);
        }
    
        public User(long id, String username, int imageRes) {
            init(id,username, imageRes);
    
        }
    
        private void init(long id, String username, int imageRes) {
            this.id=id;
            this.username = username;
            this.imageRes = imageRes;
        }
    }
    
    public class Animal {
        private int animalType;
    
        public Animal() {
            this(1); //here this(1) internally make call to Animal(1);
        }
    
        public Animal(int animalType) {
            this.animalType = animalType;
        }
    }
    
     public class Example {
       
          private String name;
       
          public Example() {
              this("Mahesh");
          }
    
          public Example(String name) {
              this.name = name;
          }
    
     }