问题很简单,但我不确定是否可以这样做......
如果我们有像
这样的课程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的类。
有趣的是,为了允许方法链接,setter返回this
。
所以我们可以这样做:
A a = new A(0);
a.setFoo(1).doSomething();
这里的问题是当我尝试扩展该类时添加一些实现这样的接口的功能
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
的实例,而且在methodI
中不存在...
任何解决方法?感谢。
顺便说一下,我只是简单地编写了一个基本代码来理解,但是如果你想了解更多,我只是想扩展 libgdx 的一些基本类(比如Math.Vector2
,Math.Vector3
)来实现 Poolable 。
答案 0 :(得分:5)
B类可以覆盖方法setFoo并将返回类型更改为B,因为B是A的更具体的版本。重写的方法可以具有更具体的返回类型。 e.g。
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;
}
}
答案 1 :(得分:2)
你应该在这里使用泛型:
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();
答案 2 :(得分:1)
之前也遇到过这种情况。不要认为这是一个简单的解决方案。考虑覆盖所有setter方法:
class B extends A implements I {
@Override
public A setFoo(int bar) {
super.setFoo(bar);
return this;
}
}
答案 3 :(得分:0)
为了完整性(即我不认为这是更好的解决方案而不是上述方法,可能是合适的)并且肯定不是问题标题的答案,而是您问题的可能解决方案。
您可以考虑使用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);
}
}
答案 4 :(得分:-2)
只需让setFoo()返回void,然后就可以了:
B b = new B(1);
b.setFoo(2);
b.methodI();