如何扩展在他们的方法中返回 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.Vector2
、Math.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);
}
}
问题很简单,但我不确定是否可行...
如果我们有 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.Vector2
、Math.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);
}
}