当前位置: 技术问答>java相关
关于继承的问题
来源: 互联网 发布时间:2015-08-24
本文导语: class Test1 { private String s=new String("Test1 "); public void append(String a) { s += a; } public void f() { append("f() "); } public void print() { System.out.println(s); ...
class Test1 {
private String s=new String("Test1 ");
public void append(String a) {
s += a;
}
public void f() {
append("f() ");
}
public void print() {
System.out.println(s);
}
}
public class Test extends Test1 {
String s = new String("Test ");
public void f() {
append("Test.f() ");
super.f();
}
public static void main(String[] args) {
Test x=new Test();
x.f();
x.print();
System.out.println(x.s);
}
}
为什么运行结果为:
Test1 Test.f() f()
Test
为什么append()修改的是Test1的s而不是Test的s?
private String s=new String("Test1 ");
public void append(String a) {
s += a;
}
public void f() {
append("f() ");
}
public void print() {
System.out.println(s);
}
}
public class Test extends Test1 {
String s = new String("Test ");
public void f() {
append("Test.f() ");
super.f();
}
public static void main(String[] args) {
Test x=new Test();
x.f();
x.print();
System.out.println(x.s);
}
}
为什么运行结果为:
Test1 Test.f() f()
Test
为什么append()修改的是Test1的s而不是Test的s?
|
别人的回答,转载一下!
回复人: illia(蓝雪) ( ) 信誉:100 2002-3-28 0:20:06 得分:10
在java中,当子类定义了与父类同名的属性变量时,即出现了子类变量对同名父类变量的隐藏。
所谓隐藏就是指子类拥有两个同名变量,一个继承自父类,一个由自己定义。当子类执行继承自父类的操作时,处理的是继承自父类的变量,当执行由子类本身定义的操作时,处理就是自己定义的变量,而把继承自父类的变量“隐藏”起来。
也就是说,在Derived类创建的时候,分配了两个x的空间,但是对于外部来说,它只有一个变量x。
而方法的继承则和域中变量的继承不一样:当父类中一个方法被子类覆盖时,它所占用的内存空间将被完全清空,父类的方法在子类中将不复存在。
Base类的对象b的创建是通过new一个Derived来完成的,因此b这个句柄指向的对象其实是Derived类的一个实例,在实例b中,内存空间中分配了两个同名的x,b.show()由于在Derived类里被覆盖了,调用的也是Derived类里面的show()方法,因此这个show()操作的是Derived类里面的x,所以值为2。而b.x=3是因为b的类型是Base,b.x是显式的调用Base类里继承的变量x,所以显示的是Base类所赋的值。
回复人: illia(蓝雪) ( ) 信誉:100 2002-3-28 0:20:06 得分:10
在java中,当子类定义了与父类同名的属性变量时,即出现了子类变量对同名父类变量的隐藏。
所谓隐藏就是指子类拥有两个同名变量,一个继承自父类,一个由自己定义。当子类执行继承自父类的操作时,处理的是继承自父类的变量,当执行由子类本身定义的操作时,处理就是自己定义的变量,而把继承自父类的变量“隐藏”起来。
也就是说,在Derived类创建的时候,分配了两个x的空间,但是对于外部来说,它只有一个变量x。
而方法的继承则和域中变量的继承不一样:当父类中一个方法被子类覆盖时,它所占用的内存空间将被完全清空,父类的方法在子类中将不复存在。
Base类的对象b的创建是通过new一个Derived来完成的,因此b这个句柄指向的对象其实是Derived类的一个实例,在实例b中,内存空间中分配了两个同名的x,b.show()由于在Derived类里被覆盖了,调用的也是Derived类里面的show()方法,因此这个show()操作的是Derived类里面的x,所以值为2。而b.x=3是因为b的类型是Base,b.x是显式的调用Base类里继承的变量x,所以显示的是Base类所赋的值。
|
属性是不会被重载的,所以当你在Test中调用append方法时,它首先在test中寻找,没找到后会到父类Test1中寻找,然后执行s+=a;因为属性不能重载,所以它引用的是自己的s(Test1)。
|
楼上的说的对。属性不能被重载,只能被覆盖。
还有私有变量或方法,只能在定义他的类里面调用。,
还有私有变量或方法,只能在定义他的类里面调用。,
|
Re:奇怪,我在jb7中跟踪调试时,s的值一直显示:Test,但最后却打印出Test1 Test.f() f() ,不知是不是一个bug?
你跟踪的是类Test中的s吧?但打印的是Test1中的s.
你跟踪的是类Test中的s吧?但打印的是Test1中的s.
|
楼上的都正确,关键是属性没有多态性。而方法是有多态性的,所以出现如上结果。
|
属性没有多态性。而方法是有多态性的,