Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 方法链接+;继承2次或2次以上_Java_Inheritance_Chaining - Fatal编程技术网

Java 方法链接+;继承2次或2次以上

Java 方法链接+;继承2次或2次以上,java,inheritance,chaining,Java,Inheritance,Chaining,我不希望能够将构建在彼此之上的多个向量类方法链起来。我希望能够扩展这个类 这是2d的一个: 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(doub

我不希望能够将构建在彼此之上的多个向量类方法链起来。我希望能够扩展这个类

这是2d的一个:

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;
    }

}
公共类Vec2{
公共双x,y;
公共Vec2(){
}
公共向量2(双x,双y){
这个.x=x;
这个。y=y;
}
公共C添加(双x,双y){
这个.x+=x;
这个.y+=y;
返回(C)本条;
}
}
这适用于带有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{
双z;
公共Vec3(){}
公共向量3(双x、双y、双z){
super(x,y);
这个。z=z;
}
公共C加法(双x,双y,双z){
超级。添加(x,y);
这个.z+=z;
返回(C)本条;
}
}
但是当使用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);
Vec3 a=新的Vec3();
//------------------------------------------------------------>.Vec2中的add()无法应用
a、 添加(10,20)。添加(10,20,10)。添加(10,20)。添加(10,20)。添加(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;
    }
}
类Vec3扩展了Vec2{
//像以前一样。。。
公共向量3添加(双x、双y、双z){
超级。添加(x,y);
这个.z+=z;
归还这个;
}
}
因为当我做一个Vec4的时候,我必须覆盖Vec3中的每个方法


有没有解决这个问题的方法(语法)?无论它返回什么,都会返回正确的类。

问题在于,您的定义中有很多“原始”类型,例如

Vec2 < C extends Vec2 >
                 ----
                 raw type!
但是等一下,我们如何向
Vec3
提供
This

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

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

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;
    }
}
接口向量{
C添加(C);
}
类Vec2实现了Vec{
公共双x,y;
公共Vec2(){
}
公共向量2(双x,双y){
这个.x=x;
这个。y=y;
}
公共Vec2添加(Vec2 c){
这个.x+=c.x;
这个.y+=c.y;
归还这个;
}
}
静态类Vec3实现了Vec{
Vec2-Vec2;
双z;
公共Vec3(){
这个(0,0,0);
}
公共向量3(双x、双y、双z){
vec2=新的vec2(x,y);
这个。z=z;
}
公共Vec3添加(Vec3 c){
添加(新的vec2(c.vec2.x,c.vec2.y));
这个.z+=z;
归还这个;
}
}

,但我不确定它可以降低多少级别。我不认为你可以走得更远,在这一点上,如果没有开发人员的参与,无论它如何不断返回正确的类几乎是不可能的。@clankill3r-好吧,你不能否认你基本上是正确的,除非你不是这样指定自引用类型的。改为使用:
Vec2
,并将OP的代码保持为(即返回
C
)@Bohemian-这是流行的做法,但我反对。边界是复杂的、令人困惑的,并且无论如何都不是类主体所需要/使用的。呼叫站点不能真正使用绑定来强制执行
C
是“自我类型”。因此,我建议我们只采用一个常规名称,
This
,来表示这种类型变量;忘记束缚吧。
public class V3 extends Vec3<V3>{}
    V3 a = new V3();
    a.add(10, 20).add(10, 20, 10).add(10, 20).add(10, 20).add(10, 10, 20);
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;
    }
}