为什么this()和super()都不能在构造函数中一起使用?

时间:2012-04-30 09:21:55

标签: java inheritance constructor

为什么this()super()不能在构造函数中一起使用?

合并这样的东西的原因是什么?

11 个答案:

答案 0 :(得分:33)

this(...)将调用同一个类中的另一个构造函数,而super()将调用超级构造函数。如果构造函数中没有super(),则编译器将隐式添加一个super

因此,如果两者都被允许,你最终可能会两次调用class A { public A() { this( false ); } public A(boolean someFlag) { } } class B extends A { public B() { super(); } public B( boolean someFlag ) { super( someFlag ); } public B ( int someNumber ) { this(); // } } 构造函数。

示例(不要在参数中查找):

new B(5)

现在,如果您调用 this( false); A() ---------------> A(false) ^ | | super(); | | this(); B() <--------------- B(5) <--- you start here ,则会调用以下构造函数:

this()

更新

如果您能够使用super() this( false); A() ---------------> A(false) ^ ^ | | | super(); | super( true ); <--- Problem: should the parameter be true or false? | | | this(); | B() <--------------- B(5) <--- you start here ,最终可能会遇到以下情况:

注意:这是为了显示可能出现的问题,如果你被允许这样做 - 幸运的是你没有这样做)

A(boolean)

正如您所看到的,您遇到的问题是A()构造函数可以使用不同的参数调用,您现在必须以某种方式决定应该使用哪个。此外,其他构造函数(B()super( true ))可能包含现在可能无法正确调用的代码(即乱序等),因为调用this()会绕过它们{{1}} 1}}不会。

答案 1 :(得分:8)

super()this()之间存在差异。

super() - 调用基类构造函数而
this() - 调用当前类构造函数。

this()super()都是构造函数调用。
构造函数调用必须始终是第一个语句。所以我们不能将两个语句作为第一个语句,因此我们可以调用super()或者我们可以从构造函数中调用this(),但不能同时调用它们。

答案 2 :(得分:4)

this()super()都是构造函数调用,构造函数调用必须是构造函数中的第一个(也是唯一的)调用。否则,在实例化单个对象时,将多次调用Object构造函数。

答案 3 :(得分:2)

  • 我们在构造函数链中使用 this()关键字来访问相同类的构造函数
  • 当我们想要在继承中访问直接父类的构造函数时,我们使用 super()关键字。

并且两者都有一个条件,它们必须在您正在使用的构造函数的第一行中声明。这就是我们无法在单个构造函数中使用这两者的原因,因为您只能在第一行中编写一件事。

答案 4 :(得分:1)

因为它没有意义。构造函数必须调用this()super()(隐式或显式)。 this()调用另一个构造函数,该构造函数必须像以前一样调用this()super()等。因此,调用this()super()的构造函数最终会调用super()两次。

答案 5 :(得分:0)

比较下面的例子。类FirstChild在2个构造函数中设置实例变量名称,因为需要调用super()来排除从第一个构造函数调用第二个构造函数。

在SecondChild类中引入了第三个私有构造函数,它接受2个参数 - 第一个传递给supper(),第二个用于设置名称。前2个构造函数调用第三个。 Super()只调用一次,实例变量也只在一个构造函数中设置。代码生成相同的结果,而无需在相同的构造函数中调用super()和this()。

class FirstChild extends ConstructorTest{
    private String name = null;
    public FirstChild(){
        super("super text 1");
        //this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
        name = "Unknown";
    }
    public FirstChild(String name){
        super("super text 2");
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class SecondChild extends ConstructorTest{
    private String name = null;
    public SecondChild(){
        this("super text 1", "Unknown");
    }
    public SecondChild(String name){
        this("super text 2", name);
    }
    private SecondChild(String superStr, String name)
    {
        super(superStr);
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

public class ConstructorTest{
    public ConstructorTest(String str){
        System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
    }
    public static void main(String... args)
    {
        System.out.println("Hello from main, FirstChild results:");
        FirstChild fc1 = new FirstChild();
        FirstChild fc2 = new FirstChild("John");
        System.out.println("           child fc1 name: " + fc1.getName());
        System.out.println("           child fc2 name: " + fc2.getName());
        System.out.println("Hello from main, SecondChild results:");
        SecondChild sc1 = new SecondChild();
        SecondChild sc2 = new SecondChild("John");
        System.out.println("           child sc1 name: " + sc1.getName());
        System.out.println("           child sc2 name: " + sc2.getName());
    }
}

答案 6 :(得分:0)

因为如果在构造函数中一起使用this()super(),则会产生编译时错误。因为this()super()必须是第一个可执行语句。如果你先写this()而不是super()将成为第二个陈述,反之亦然。这就是我们无法一起使用this()super()的原因。

答案 7 :(得分:0)

this()和super(),两者都是构造函数,这就是为什么必须是第一个语句。但我们可以在一个程序中使用它们。

this():用于调用同一类Default或Parametrized Constructor。

super():用于调用立即超级/父类的默认或参数化构造函数。

//Super Class
    public class SuperConstructor {
    SuperConstructor(){
        this(10);
        System.out.println("Super DC");
    }

    SuperConstructor(int a){
        this(10,20);
        System.out.println("Suer SPC with Iteger");
    }

    SuperConstructor(int i,int j){
        System.out.println("Super with  DPC with Iteger and Integer");
    }
}


//subclass
    public class ThisConstructor extends SuperConstructor{  
    ThisConstructor(){
        this(10,20);
        System.out.println("Subcalss DC ");//DC Default Constructor
    }

    ThisConstructor(int i){
        super(i);       
        System.out.println("Subcalss  SPC with Iteger");//SPC Single Parameterized Constructor
    }

    ThisConstructor(int i, String s){
        this();
        System.out.println("Subcalss  DPC with Iteger and String");//DPC double Parameterized Constructor
    }

    ThisConstructor(int i,int age){
        super(i,age);
        System.out.println("Subcalss  DPC with Iteger and Integer");
    }

    public static void main(String []k){
        System.out.println("=================Frist time Calling ==========================\n");
        ThisConstructor t = new ThisConstructor(1);


        System.out.println("=================Second time Calling ==========================\n");
        ThisConstructor t1 = new ThisConstructor(1,2);
    }
}

答案 8 :(得分:0)

super()-引用直接父类实例。 可用于调用直接父类方法。 this()-引用当前的类实例。 可用于调用当前的类方法。

答案 9 :(得分:0)

不能在构造函数中同时使用 this() 和 super() 因为 this() 和 super() 必须首先在构造函数块中执行。否则它会显示编译器错误

答案 10 :(得分:0)

由于构造函数调用必须是方法中的第一条语句,所以如果我们在一个方法中同时定义 this 和 super 构造函数,那么就会发生如下冲突。 假设首先调用此构造函数,然后它将检查当前类构造函数,如果在当前类构造函数中我们有另一个方法调用或语句。所以在这个调用中,当前类构造器中的所有方法和语句都会在调用超类构造器之前被调用,然后它会拒绝“构造器调用必须是方法中的第一个语句”这一说法