Java:为什么“this()”不能被覆盖?

4
请看下面的示例:
class A {
   A() { this(1); }
   A(int i) { System.out.println("A" );  }
}

class B extends A {
    B() {}
    B(int i) {  System.out.println("B" );  }
}

public class Test
{
    public static void main(String[] args)   {        
       A o =  new B();
    }
}

输出:
A

问题1:似乎java不会对"this(1)"执行后期绑定。这在编译时已经确定。请确认。

问题2:Java不对任何构造函数执行后期绑定。请确认。

问题3:这是否意味着构造函数是隐式的final?


6个回答

7

构造函数不可被覆盖,因为它们完全不遵循继承规则。它们不能遵循继承规则是因为你需要一个简单的顺序来构建你的对象。

例如,在你的示例中,如果你可以覆盖A(int)构造函数,A()将调用B(int),但B(int)隐式调用了super(),即A(),你会进入无限递归。

通常认为构造函数调用可重写方法是不好的实践。因此,让构造函数自动执行这个操作是一个非常糟糕的想法。

如果构造函数像static final方法一样是final的,那么你也不能隐藏它们,但你可以这样做,所以我认为它们也是final


2

Java不会重写构造函数。

A o = new B(); 它将调用B(),在其中将调用super()。

A()将被调用,在这里您正在调用this(1),这意味着它将调用A(1),因此没有什么奇怪的。当谈论构造函数时,所有内容都在编译时决定。

答案:

Q1:似乎Java不会对"this(1)"执行后期绑定。已在编译时决定。请确认。

是的,只有在编译时才会决定构造函数。

Q2:Java不会对任何构造函数执行后期绑定。请确认。

由于不重写,因此没有后期绑定。

Q3:这是否意味着构造函数隐式为final?

不,它们不是final,但您无法覆盖它们。

编辑: 子类从其超类继承所有成员(字段、方法和嵌套类)。构造函数不是成员,因此它们不会被子类继承,但是可以从子类中调用超类的构造函数请参阅Java文档


1

问题1:真的

问题2:这不是关于构造函数的问题,更多的是关于this的问题。this总是指向类或超类中存在的方法/字段,而不是子类中的方法/字段。这是有道理的,因为父类不知道子类的实现。

问题3:有点像,构造函数是特殊的方法,重写它们没有意义,因为它们是链接在一起的。


0

'"this()"没有被重写' 这句话没有任何意义,你的其他问题也一样。

这里发生的所有事情就是 B 的构造函数都隐式地调用了 super(),因为你没有编写其他内容,而 super() 就是 A(),它调用了 this(1)


0

当您创建子类的实例时,您必须调用超类的构造函数。

如果您没有指定构造函数,则会为您调用默认(无参数)构造函数。

换句话说,在B中的无参构造函数实际上被执行为:

B() {
    super();
}

这并没有回答问题。他知道A::A()被隐式调用了。他困惑的是为什么A::A()中的this(1)调用的是A::A(1)而不是B::B(1) - Corbin

0

当您实例化子类构造函数时,它会在执行自己的任务之前首先调用其超类的默认构造函数。这是通过隐式方式或通过super()引用完成的。

因此,对B()的调用将调用构造函数A(),该构造函数将调用A(1)

同样,如果您调用B(2),输出将是(它将调用默认构造函数A(),然后调用A(1))

A
B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接