方法链接+继承2次或更多次

时间:2015-06-10 17:58:33

标签: java inheritance chaining

我想能够将多个构建在彼此之上的向量类链接起来。我希望能够扩展该课程。

这是第二个:

public class Vec2 < C extends Vec2 > {

    public double x, y;

    public Vec2() {
    }

    public Vec2(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public C add(double x, double y) {
        this.x += x;
        this.y += y;
        return (C) this;
    }

}

这适用于带有z元素的向量。

class Vec3 < C extends Vec3 > extends Vec2<Vec3> {

    double z;

    public Vec3(){}

    public Vec3(double x, double y, double z) {
        super(x, y);
        this.z = z;
    }

    public C add(double x, double y, double z) {
        super.add(x, y);
        this.z  += z;
        return (C) this;
    }
}

但是当使用Vec3时,我会在连续两次使用Vec2的方法后再返回Vec2。

 Vec3<Vec3> a = new Vec3<>();
 // ------------------------------------------------->.add() in Vec2 cannot be aplied
 a.add(10, 20).add(10, 20, 10).add(10, 20).add(10, 20).add(10, 10, 20);

我不想写这样的课:

class Vec3 extends Vec2<Vec3> {

    // constructor etc. like before...

    public Vec3 add(double x, double y, double z) {
        super.add(x, y);
        this.z  += z;
        return this;
    }
}

因为当我以Vec4为例时,我必须覆盖Vec3中的每个方法。

这个问题有没有办法(语法)?无论什么,它一直在返回正确的班级。

2 个答案:

答案 0 :(得分:2)

问题是你有很多&#34; raw&#34;输入您的定义,例如

Vec2 < C extends Vec2 >
                 ----
                 raw type!

几轮后,您将获得原始类型,而删除会使CVec2相同。

我们可以使用类型变量This作为&#34;自我类型&#34;

public class Vec2<This> {

    public This add(double x, double y) {
        this.x += x;
        this.y += y;
        return (This) this;
    }

}

public class Vec3<This> extends Vec2<This> {

    public This add(double x, double y, double z) {
        super.add(x, y);
        this.z  += z;
        return (This) this;
    }
}

public class Vec4<This> extends Vec3<This> {

etc.

但是等一下,我们如何向This提供Vec3

    Vec3<Vec3<Vec3<......>>>    ???

我们可以使用助手类

public class V3 extends Vec3<V3>{}

现在一切正常; add()中的所有V3方法都会返回V3

    V3 a = new V3();
    a.add(10, 20).add(10, 20, 10).add(10, 20).add(10, 20).add(10, 10, 20);

答案 1 :(得分:0)

您无法完全按照预期实现代码,但以下编译并且我相信会捕获您的意图:

interface Vec<C extends Vec<C>> {
    C add(C c);
}

class Vec2 implements Vec<Vec2> {
    public double x, y;
    public Vec2() {
    }

    public Vec2(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public Vec2 add(Vec2 c) {
        this.x += c.x;
        this.y += c.y;
        return this;
    }
}

static class Vec3 implements Vec<Vec3> {
    Vec2 vec2;
    double z;
    public Vec3() {
        this(0,0,0);
    }

    public Vec3(double x, double y, double z) {
        vec2 = new Vec2(x, y);
        this.z = z;
    }

    public Vec3 add(Vec3 c) {
        vec2.add(new Vec2(c.vec2.x, c.vec2.y));
        this.z  += z;
        return this;
    }
}