是继承类在内存中的加载形式还是多态问题引起的超类this变为子类对象?

来源:百度知道 编辑:UC知道 时间:2024/05/16 12:44:00
为了方便,我将程序简化了。

public class A{
public A(){
System.out.println("A constructor:" + this);
}

public String toString(){
return "class A";
}

}

public class B extends A{
public B(){
System.out.println("B constructor:" + this);
}

public String toString(){
return "Class B";
}

}

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

执行结果为
A constructor:class A
A constructor:class B
B constructor:class A class B

我的分析:A a = new A()调用了类A的构造函数打印了类A的toString(),第一行结果没问题。
第二行,B b = new B();首先调用了类A的构造函数,打印了B(A的子类)的toString()方法,我认为这是因为多态造成的,类A中this是类B的对象。可是老师说,是因为继承类在内存中加载的缘故。加载的时候将超类加载到子类中,所以,类A中的this是类B的对象。

可是如果将类A中多加任何一个方法,用类A中this调用,都可以调用类A的方法,如果说this是类B的,那么就不能调用。 所以我认为出现第二行结果是因为多态造成的。

各位前

程序的结果你写的也有问题吧?
执行结果应该为
A constructor:class A
A constructor:class B
B constructor:class B

你老师讲的不对。这里是多态。在执行B b = new B(); 的时候,因为B是A的子类,所以先调用了A的构造方法,对于特殊变量this,每当调用一个实例方法时,this变量将被设置成引用该实列方法的特定的类对象。此时调用的是A的方法,但是由于方法重载,所以调用B的toString方法。

可以换个不重载的试试就行了比如:
public class A
{
public A()
{
System.out.println("A constructor:" + this.hashCode());
}

public int hashCode()
{
return 400;
}

}

class B extends A
{
public B()
{
System.out.println("B constructor:" + this);
}

public String toString()
{
return "Class B";
}

}

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

因为在继承条件下,一旦调用子类构造器,子类构造器会先去调用相应的父类构造器,然后在调用自身的构造