Java-继承的Fluent方法返回类型以返回事件类';类型,而不是父项';s
当您采用流畅的方法时,可能会出现以下情况:Java-继承的Fluent方法返回类型以返回事件类';类型,而不是父项';s,java,inheritance,fluent,Java,Inheritance,Fluent,当您采用流畅的方法时,可能会出现以下情况: public class Foo<T extends a>{ public Foo<T> someMethod(){ System.out.println("foo"); return this; } } public class Bar<T extends b> extends Foo<T> { public Bar&l
public class Foo<T extends a>{
public Foo<T> someMethod(){
System.out.println("foo");
return this;
}
}
public class Bar<T extends b> extends Foo<T> {
public Bar<T> barMethod(){
System.out.println("bar");
return this;
}
}
public class a{}
public class b extends a{}
公共类Foo{
公共Foo方法(){
System.out.println(“foo”);
归还这个;
}
}
公共类Bar扩展了Foo{
公共酒吧法(){
系统输出打印项次(“bar”);
归还这个;
}
}
公共a类{}
公共类b扩展了{}
fluent接口的一个优点是可以链接方法调用,但尽管Bar继承了someMethod(),但返回类型是Foo而不是Bar,这将打破以下链接:
new Bar<b>().someMethod().barMethod();
newbar().someMethod().barMethod();
一个答案是为每个继承的方法添加@Overrides,这样Bar就有了额外的方法:
@Override
public Bar<T> someMethod(){
System.out.println("foo");
return this;
}
@覆盖
公共酒吧法(){
System.out.println(“foo”);
归还这个;
}
但在大型类和扩展类层次结构中,这肯定会导致冗余混乱?!是否有一个合适的返回类型给fluent方法,每个继承它的类都将返回其特定类型的对象(这样我们就可以在没有强制转换的情况下链接方法)
我试过:
public <U extends Foo<T>> U someMethod(){
System.out.println("foo");
return this;
}
public方法(){
System.out.println(“foo”);
归还这个;
}
唉,没用。我希望有人知道这个问题的简单而优雅的解决方案。这个项目很大,因此如果可能的话,它需要可维护和可扩展
感谢您在此场景中提供的任何帮助。您可以做的是定义
barMethod
方法摘要,因此现在您可以在Foo
类型中调用它
public abstract class Foo<T extends a> {
public Foo<T> someMethod() {
System.out.println("foo");
return this;
}
public abstract Foo<T> barMethod();
}
公共抽象类Foo{
公共Foo方法(){
System.out.println(“foo”);
归还这个;
}
公共抽象Foo-barMethod();
}
现在你可以很容易地打电话了
new Bar<b>().someMethod().barMethod();
newbar().someMethod().barMethod();
如果您不介意取消选中的强制转换,您可以这样做:
public class Foo<T, F extends Foo<T, F>> {
public F someMethod() {
System.out.println("foo");
return (F) this; // <--- That's the unchecked cast! Tucked safely away.
}
public static void main(String[] args) {
new Bar<String>().someMethod().barMethod();
}
}
class Bar<T> extends Foo<T, Bar<T>> {
public Bar<T> barMethod() {
System.out.println("bar");
return this;
}
}
公共类Foo{
公共F方法(){
System.out.println(“foo”);
返回(F)这;//这种方法的问题是,它阻止我们直接实例化Foo,我仍然需要这样做。@HodeCode。所以你不想添加抽象方法,不想重写,也不想进行类型转换。如果有办法的话,这将很难。让我们看看是否有人能想出一个解决方案。但我没有如果你能解决所有的问题,那就有一个解决办法了。但我还是不能确定。然后你就必须解决它。Java似乎没有优雅地促进这种体系结构,这真是太遗憾了。我正试图让客户端尽可能直接地使用这个库,而不让任何难看的代码乱放casts等@HodeCode它是抽象类的很好的候选,因为你已经有了它的子类,并且在Foo类中有常见的功能。但是仍然有一个casting
,OP不想要。我不知道为什么。嗯。但是这个casting更好。它在一个地方。所以,OP应该可以使用它。否则上帝保佑他。@RohitJain看到评论我疯了关于以上答案:这是一个可用性的问题,试图让它成为一个非常简单的库,供客户在他们的项目中使用。尽管Marko Topolnik的解决方案很有趣,但我没有考虑到一些问题。似乎一些描述的类型转换是不可避免的?@MarkoTopolnik。是的,这就是为什么在我的评论结束时,我补充说这是一个更好的铸造,因为它在一个地方。:)对不起,在看到你的评论中的编辑之前回答。删除我的。我遇到了更多的困难与这种方法…我仍然怀疑它是否真的在更深层次上可行。