带有超级关键字的Java通用方法

时间:2015-05-11 12:59:56

标签: java generics

我现在正在练习Java并试图深入研究泛型。我想让这段代码工作:

public class TwoD { // simple class to keep two coordinate points
    int x, y;

    TwoD(int a, int b) {
        x = a;
        y = b;
    }
}

public class ThreeD extends TwoD { //another simple class to extend TwoD and add one more point
    int z;

    ThreeD(int a, int b, int c) {
        super(a, b);
        z = c;
    }
}
public class FourD extends ThreeD { //just like previous
    int t;

    FourD(int a, int b, int c, int d) {
        super(a, b, c);
        t = d;
    }
}
public class Coords<T extends TwoD> { //class to keep arrays of objects of any previous class
    T[] coords;

    Coords(T[] o) {
        coords = o;
    }
}

现在我想制作一个方法,它将使用TwoD和ThreeD的对象而不是FourD。 我试过了:

static void showXYZsub(Coords<? super FourD> c) {
        System.out.println("X   Y   Z:");
        for (int i = 0; i < c.coords.length; i++)
            System.out.println(c.coords[i].x + "    " + c.coords[i].y + 
                    "   " + c.coords[i].z);
        System.out.println();
    }

但我收到错误&#34; z无法解析或不是字段&#34;。

据我所知,关键字super应该过滤任何扩展FourDFourD本身的类的对象,但即使我改变FourDThreeDTwoD,错误将是相同的。

即。如果我使用super,则只能显示TwoD字段,但如果extends,则一切正常 Coords班级有问题还是什么?请帮忙。

对不起,感到遗憾。

---编辑:调用showXYZsub

FourD fd[] = { 
new FourD(1, 2, 3, 4), new FourD(6, 8, 14, 8), new FourD(22, 9, 4, 9),
        new FourD(3, -2, -23, 17) };
Coords<FourD> fdlocs = new Coords<FourD>(fd);
showXYZsub(fdlocs);

3 个答案:

答案 0 :(得分:1)

Coords<? super FourD> c

这意味着:cCoords,其中type参数是某种未知类型,是FourD的超类型。

成员变量z是在ThreeD中定义的,它是FourD的超类型。但是,? super FourD并不保证T类型至少是ThreeD。例如,它也可以是TwoDObject,它们也是FourD的超类型。

因此,您无法访问成员变量z,因为类型T可能没有此成员变量。

看起来你确实想要使用:

Coords<? extends ThreeD> c

答案 1 :(得分:0)

你要做的事情是不可能的,因为当争论是一个双点时,你将如何获得point.z

你说

be using objects of TwoD and ThreeD but not FourD 

为什么要限制FourD个对象? 通过继承,每FourD 一个ThreeD。因此,如果某些东西需要ThreeD,它也应该能够处理FourD s。

请注意,这是有道理的:如果你的函数需要三维点,它就无法处理2D,因为它缺少一个维度,但是会有4D没有问题,只是忽略了额外的一个。

答案 2 :(得分:0)

当您说Coords<? super FourD>时,它意味着Java Allow every class which is a super class of FourD and it means TwoD and ThreeD are allowed。 Actualy它意味着这个家庭的一个类。请查看此question了解更多信息。

现在这两个classe都有xy参数,所以它意味着我们得到的任何允许的类,我们可以安全地打印它们(xy)。但是当你包含z时,它在类TwoD中没有存在,所以如果你传递了一个对象,程序将会失败。所以Java采取了防御性的方法而且不允许你。

您想要的确切地说可能是ThreeDFourD。现在,类FourD扩展了ThreeD,因此关系Coords<? extends ThreeD>应该可以正常工作,因为它意味着Allow ThreeD or any one who extends ThreeD (read FourD)这就是我们想要的。那是那种情况下的解决方案。

<强>参考文献: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html