如何扩展在他们的方法中返回 this 的 class

How to extend a class that is returning this in their methods

问题很简单,但我不确定是否可行...

如果我们有 class 喜欢

class A {
    private int foo;

    public A(int bar) {
       this.foo = bar;
    }

    public A setFoo(int bar) {
       this.foo = bar;
       return this;
    }

    public int getFoo() {
       return this.foo;
    }

    public void doSomething() {
       this.foo++;
    }
}

我们可以看到它只是一个带有私有成员和 setter/getter 的 class。 有趣的是,为了允许方法链接,setter 返回 this.

所以我们可以这样做:

A a = new A(0);
a.setFoo(1).doSomething();

这里的问题是当我尝试扩展 class 添加一些实现这样的接口的功能时

class B extends A implements I {
    public B(int bar) {
        this.super(bar);
    }

    public void methodI() {
        // whatever
    }
}

看起来不错,直到我开始这样使用它

B b = new B(1);
b.setFoo(2).methodI();

因为 setFoo 实际上返回的是 A 的实例,而不是 B 的实例,并且在 A 中 methodI 不存在...

有什么解决方法吗?谢谢。

顺便说一句,我只是写了一个基本代码来简单理解,但如果你想了解更多,我只是想扩展[=40=的一些基本classes ]libgdx(如Math.Vector2Math.Vector3)实现Poolable.

只需让 setFoo() return 无效,然后您可以:

B b = new B(1); b.setFoo(2); b.methodI();

你应该在这里使用泛型:

public class A<T extends A<?>> {

    public T self() {
        return (T) this;
    }

    private int foo;

    public A(int bar) {
       this.foo = bar;
    }

    public T setFoo(int bar) {
       this.foo = bar;
       return self();
    }

    public int getFoo() {
       return this.foo;
    }

    public void doSomething() {
       this.foo++;
    }

}

public class B<T extends B<?>> extends A<T> implements I {

    public B(int bar) {
        this.super(bar);
    }

    public void methodI() {
        // whatever
    }
}

现在您将能够使用这样的链式调用:

B b = new B(1);
b.setFoo(2).methodI();

Class B 可以覆盖方法 setFoo 并将 return 类型更改为 B,因为 B 是 A 的更具体的版本。被覆盖的方法可以具有更具体的 return类型。例如

class B extends A implements I {
    public B(int bar) {
        this.super(bar);
    }

    public void methodI() {
        // whatever
    }

    @Override
    public B setFoo(int bar) {
       this.foo = bar;
       return this;
    }
}

之前也运行参与过这个。不要认为有一个简单的解决方案。考虑覆盖所有 setter 方法:

class B extends A implements I {
    @Override
    public A setFoo(int bar) {
        super.setFoo(bar);
        return this;
    }
}

为了完整性(即我不认为这是比上述更好的解决方案,只是可能是合适的)当然不是你问题标题的答案,而是一个可能的解决您的问题。

您可以考虑使用Java 8 提供的default 方法。它专门用于向现有类 添加功能。

// From LibGDX Pool.Poolable
interface Poolable {

    public void reset();
}

// Class A untouched.
class A {

    private int foo;

    public A(int bar) {
        this.foo = bar;
    }

    public A setFoo(int bar) {
        this.foo = bar;
        return this;
    }

    public int getFoo() {
        return this.foo;
    }

    public void doSomething() {
        this.foo++;
    }
}

// Extend Poolable to add the functionality.
interface PoolableVector extends Poolable {

    default void reset() {
        // Not sure what you want to do here.
    }
}

// A Poolable A trivially made.
class B extends A implements PoolableVector {

    public B(int b) {
        super(b);
    }

}