使用超级AND实例变量的构造函数

时间:2013-12-16 02:41:45

标签: java oop constructor super

我在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)?

6 个答案:

答案 0 :(得分:7)

This is what we call hiding.假设您的班级Point也声明了两个名为xy的实例变量,那些就是您要设置的变量

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.xsuper.y

删除x和y(不使用它们)或引用点数

当你在构造函数中调用super()时,Point会设置其x和y字段。你自己创建了一个x和y,默认为0.所以当你引用fp.x和fp.y时,你总是得到你的(总是0)

答案 2 :(得分:5)

您的班级FourDPoint包含影响超级点xy的本地成员,注释掉这两行 -

// int x;
// int y;

答案 3 :(得分:3)

您永远不会将xy的值设置为某个值,因此它们将始终返回0.

是的,你调用超级构造函数但这没关系:即使x中有变量yPoint,它们也会被名为相同的变量隐藏FourDPoint

更不用说Point中的变量也应该是protected

答案 4 :(得分:0)

工作流是这样的:初始化父成员,调用父构造函数,初始化类成员(基元设置为0),执行类构造函数的代码。

答案 5 :(得分:0)

是的,因为你覆盖了它们,所以它们优先。就这么简单。