如何设计此方法的签名

时间:2015-02-15 20:21:08

标签: java interface polymorphism

我需要定义一个方法,它接受一个请求并返回一个响应:

  public MyResponse submit(MyRequest request){                      A
      ....
  }

这看起来很简单。但是:

MyRequest可以有许多子类

 public class HolidayRequest extends MyRequest {}
 public class FundingRequest extends MyRequest {}
 public class BudgetRequest extends MyRequest {}

同样适用于响应类:

 public class HolidayResponse extends MyResponse {}
 public class FundingResponse extends MyResponse {}
 public class BudgetResponse extends MyResponse {}

方法submit的用户可以传入任何类型的请求并获取相应的响应对象,例如:Pass in HolidayRequest将返回HolidayResponse。

虽然上面定义的接口仍然有效,但用户必须将submit的返回值从MyResponse转换为特定的响应类型。

然后我想把方法改为:

  public <T extends MyResponse, S extends MyRequest>                B
  T submit(S request){
      ....
  }

这允许返回类型是特定类型而不是父类型。但是,用户仍然可以编写如下代码:

  HolidayResponse response = submit(new FundingRequest());

并且代码仍然会编译但在运行时失败。

然后我意识到提交方法不需要知道它是哪种类型的请求,因此不需要为MyRequest使用类型参数,我想我可以进一步简化它:

  public <T extends MyResponse>                                    C
  T submit(MyRequest request){
      ....
  }

但同样,这个问题与上面提到的问题相同,用户可以传入请求类型并期望另一种响应类型。

我的问题是我如何正确定义此方法的签名?您将使用上面A,B和C中的哪一个定义?或者可能有更合适的方式来定义它?

非常感谢。

1 个答案:

答案 0 :(得分:4)

您必须将RequestResponse

相关联

例如,将MyRequest类更改为

public abstract class MyRequest<T extends MyResponse> {

现在你的HolidayRequest看起来像是:

public class HolidayRequest extends MyRequest<HolidayResponse> {

现在,您的方法签名可以强制MyReponse对应:

public <R extends MyResponse, S extends MyRequest<R>> R submit(S request){

}