消息关闭
    暂无新消息!

有关java多态(向上转型)的问题

问题作者 : Johnnie2017-08-04发布
代码如下:
package ThinkingInJava.chapterviii.exemple.something;

class One
{
String name = "One";
int output = 0;
void output()
{
System.out.println("0");
}
}

class Two extends One
{
String name = "Two";
int output = 1;
void output()
{
System.out.println("1");
}
}

public class DataAndMethod 
{
public static void main(String[] args) 
{
One supering = new Two();
System.out.print(supering.name + " " + supering.output + " ");
supering.output();
}

}


输出结果为:
One 0 1

我的问题是:为什么 name 和 output 的值是基类 One 的值
                     而方法 output() 的内容确实子类 Two 里的?

4个回答

︿ 2
是的,new Two()的含义就是调用构造器在堆内存创建了一个Two类型的对象,One supering=是说在栈内存创建了一个One类型的变量supering。综合就是把Two的对象向上转型作为One被supering引用,但对象的实际类型还是Two。
︿ 2
这里是动态绑定的问题。成员变量,以及被final、 private  、static修饰的方法在编译时期就根据数据类型进行确定,而普通的成员方法必须要在运行时才能确定(这就是动态绑定)。运行时会根据对象的实际类型,调用他的方法,也就是子类的方法。所以结果是1的成员属性,2的成员方法。
另外补充:向上转型后不能调用子类独有方法,原因是编译检查是根据数据类型,父类没有此方法,编译不通过。
︿ 1
 在运行时环境中,通过引用类型变量来访问所引用的方法和属性时,java虚拟机采用如下绑定机制。   
  1 实例方法与引用变量 实际引用的对象 的方法绑定 属于动态绑定.由运行时jvm动态决定的。   
  2 静态方法与引用变了所声明的对象 的方法绑定 属于静态绑定 在编译阶段就已经做了绑定   
  3 成员变量 (静态和实例)与引用变量所声明的类型的成员变量绑定属于静态绑定。