Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-继承的Fluent方法返回类型以返回事件类';类型,而不是父项';s_Java_Inheritance_Fluent - Fatal编程技术网

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。是的,这就是为什么在我的评论结束时,我补充说这是一个更好的铸造,因为它在一个地方。:)对不起,在看到你的评论中的编辑之前回答。删除我的。我遇到了更多的困难与这种方法…我仍然怀疑它是否真的在更深层次上可行。