据我所知,构造函数,Instance Initialization块不会继承到子类,但是下面的代码继承了超类构造函数,为什么要调用它?
预期输出: 来自缺点2
但显示输出: --IIB-- 来自缺点1 来自缺点2
WHY? this output , *As i know "sub class should not inherit Constructor & IIB block"*
请帮我弄清楚这个概念。
public class X
{
{
System.out.println("--IIB--");
}
X()
{
System.out.println("from cons 1");
}
}
class Y extends X
{
Y()
{
System.out.print("from cons 2");
}
}
class Z
{
public static void main(String args[])
{
Y ob=new Y();
}
}
答案 0 :(得分:6)
这是因为:
Y()
{
System.out.print("from cons 2");
}
实际上变成了
Y()
{
super(); //Call to X's constructor made here even if you don't call it
System.out.print("from cons 2");
}
原因是每个Y
也是X
的一个实例。在任何子构造函数执行之前,必须首先调用该父构造函数,以保证父属性已准备就绪。
编辑:这是显示“超类构造函数不由子类继承”的示例:
class A {
A(int intForA) {
//Do stuff...
}
}
class B extends A {
B() {
this(3); //Won't compile! A's constructor isn't inherited by B
}
}
相反,我们这样做:
class B extends A {
B() {
super(3); //This compiles; we're calling A's constructor from B
}
}
答案 1 :(得分:4)
“Java编译器将初始化程序块复制到每个构造函数中。” - http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
“如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对超类的无参数构造函数的调用。” - http://docs.oracle.com/javase/tutorial/java/IandI/super.html
答案 2 :(得分:2)
当您调用子类构造函数时,它internally calls the super class constructor using the super()
(最后一个链接页面中的注释部分),在您的情况下,Y
的超类是X
。此外,实例块在构造函数中复制,因此在调用该类的任何构造函数时执行。
实例变量的初始化程序块看起来就像静态初始化程序块,但没有静态关键字:
{
// whatever code is needed for initialization goes here
}
Java编译器将初始化程序块复制到每个构造函数中。
因此输出按以下顺序排列。
--IIB--
- 来自放置在X
构造函数内的实例块。
from cons 1
- 在super()
Y()
时
from cons 2
- Y()
答案 3 :(得分:1)
在代码Y extends X
中,理想情况下,当您创建Y
类对象时,它还会创建X
类对象。所以它的块首先执行,然后是X
的构造函数,然后是Y
的构造函数。
因此你得到这样的输出。