我在21天内使用Sams Teach Yourself Java学习Java(顺便说一下,这花了我超过21天的时间)。在第5章中,最后的练习要求我创建一个类FourDPoint,它是Point的子类。我这样做了,但结果很有趣。我第一次参加演习时,这是我的代码:
import java.awt.Point;
class FourDPoint extends Point {
int x;
int y;
int z;
int t;
FourDPoint(int x, int y, int z, int t){
super(x, y);
this.z = z;
this.t = t;
}
public static void main(String[] arguments){
FourDPoint fp = new FourDPoint(5, 5, 10, 10);
System.out.println("x is " + fp.x);
System.out.println("y is " + fp.y);
System.out.println("z is " + fp.z);
System.out.println("t is " + fp.t);
}
}
结果:x为0,y为0,z为10,y为10.
我通过消除已经被感染的x和y来改变我的代码,这给了我正确的答案。我的问题:为什么我得到x是0而y是0? intitiaized x和y优先于super(x,y)?
答案 0 :(得分:7)
This is what we call hiding.假设您的班级Point
也声明了两个名为x
和y
的实例变量,那些就是您要设置的变量
super(x, y);
但是,当你引用
时System.out.println("x is " + fp.x);
System.out.println("y is " + fp.y);
您指的是FourDPoint
中声明的成员。那些尚未由您初始化,因此默认为0。
在相关的说明中,多态性不适用于实例变量。而是根据您访问它的引用类型解析该成员。
所以
FourDPoint fp = ...;
fp.x;
fp.x
会引用x
中声明的FourDPoint
成员。但
FourDPoint fp = ...;
fp.x;
((Point) fp).x;
((Point) fp).x;
会引用x
中声明的Point
成员。
答案 1 :(得分:5)
在子类中,您可以使用自己的变量对x和y变量进行阴影处理。要解决此问题,您可以使用super.x
和super.y
当你在构造函数中调用super()时,Point会设置其x和y字段。你自己创建了一个x和y,默认为0.所以当你引用fp.x和fp.y时,你总是得到你的(总是0)
答案 2 :(得分:5)
您的班级FourDPoint
包含影响超级点x
和y
的本地成员,注释掉这两行 -
// int x;
// int y;
答案 3 :(得分:3)
您永远不会将x
和y
的值设置为某个值,因此它们将始终返回0.
是的,你调用超级构造函数但这没关系:即使x
中有变量y
和Point
,它们也会被名为相同的变量隐藏FourDPoint
。
更不用说Point
中的变量也应该是protected
。
答案 4 :(得分:0)
工作流是这样的:初始化父成员,调用父构造函数,初始化类成员(基元设置为0),执行类构造函数的代码。
答案 5 :(得分:0)
是的,因为你覆盖了它们,所以它们优先。就这么简单。