我有一个看起来有点像这样的类层次结构。请注意,我的确实看起来像这样,我只是用这种方式写它,使它更短,在我看来,更清晰。
public abstract BaseClass {
private Alpha a;
private Beta b;
public Alpha getAlpha() { return a; }
public Beta getBeta() { return b; }
public BaseClass setAlpha(Alpha a) { this.a = a; return this; }
public BaseClass setBeta(Beta b) { this.b = b; return this; }
}
public Foo extends BaseClass {
@Override
public Foo setBeta(Beta b) {
super.setBeta(b);
doSomethingElse();
return this;
}
public Gamma getGamma() { return g; }
public Foo setGamma(Gamma g) { this.g = g; return this; }
}
public Bar extends BaseClass {
private Omega o;
@Override
public Bar setAlpha(Alpha a) {
super.setAlpha();
doSomethingElse();
return this;
}
public Omega getOmega() { return o; }
public Bar setOmega(Omega o) { this.o = o; return this; }
}
上面列出了更多这些方法。请注意,它们不符合相同的接口。使用Foo
和Bar
且需要调用setGamma
和setOmega
的类始终可以访问最具体的类。但是,这些相同的类还需要调用setAlpha
和setBeta
。但是,除非我覆盖它们,否则这些方法不会返回正确的类型。
选项:
BaseClass
的每个方法只是为了更改返回类型
setGamma
中声明setOmega
和BaseClass
抽象等所有方法。这可能有用,除了那时我必须为那些根本没有意义的类定义它。throw new UnsupportedOperationException()
Exception
。someBar.setOmega().setAlpha()
但不是someBar.setAlpha().setOmega()
所有这些选项看起来都很糟糕。有没有人有更好的东西?
注意:这种情况与此不太一样:Java - Inherited Fluent method return type to return incident class' type, not parent's因为它不是真正的泛型问题。
答案 0 :(得分:3)
正如@chrylis在评论中指出的那样,您可以对BaseClass
进行泛化:
public abstract class BaseClass<T extends BaseClass> {
private Alpha a;
private Beta b;
public Alpha getAlpha() {
return a;
}
public Beta getBeta() {
return b;
}
@SuppressWarnings("unchecked")
public T setAlpha(Alpha a) {
this.a = a;
return (T) this;
}
@SuppressWarnings("unchecked")
public T setBeta(Beta b) {
this.b = b;
return (T) this;
}
}
并扩展如下:
public class Foo extends BaseClass<Foo> {
private Gamma g;
@Override
public Foo setBeta(Beta b) {
super.setBeta(b);
doSomethingElse();
return this;
}
private void doSomethingElse() { }
public Gamma getGamma() {
return g;
}
public Foo setGamma(Gamma g) {
this.g = g;
return this;
}
}
public class Bar extends BaseClass<Bar> {
private Omega o;
@Override
public Bar setAlpha(Alpha a) {
super.setAlpha(a);
doSomethingElse();
return this;
}
private void doSomethingElse() { }
public Omega getOmega() {
return o;
}
public Bar setOmega(Omega o) {
this.o = o;
return this;
}
}
这引入了一些未经检查的强制警告,我压制了它。它编译,但我还没有尝试过用它做任何事情。