Java协方差
对于一个项目,我想提供一个类似工作流的通用接口,比如Java协方差,java,interface,covariance,Java,Interface,Covariance,对于一个项目,我想提供一个类似工作流的通用接口,比如 public interface IWorkflow { public void start(); public void doWork(); public void end(); } 为此,我有很多实现,比如 public class CoffeeWorkflow implements IWorkflow { public void start() { // setup cof
public interface IWorkflow
{
public void start();
public void doWork();
public void end();
}
为此,我有很多实现,比如
public class CoffeeWorkflow implements IWorkflow
{
public void start()
{
// setup coffee
// prepare dishes
// ...
}
public void doWork()
{
// drink coffee
}
public void end()
{
// wash dishes
}
}
现在我想为这些函数提供更多信息,比如
public interface IWorkflowStartArgs
{}
特别是:
public class CoffeeWorkflowStartArgs implements IWorkflowArgs
将其纳入方法中
public interface IWorkflow
{
public void start(IWorkflowStartArgs args);
public void doWork();
public void end();
}
分别地:
public class CoffeeWorkflow implements IWorkflow
{
public void start(CoffeeWorkflowStartArgs args)
{
}
}
但这不起作用,因为它不被视为实施
接口的一部分
我是否应该通过IWorkflowStartArgs并将其扔进去
有更好的解决方案吗?您可以定义如下接口
interface IWorkflow<T extends IWorkflowStartArgs>
{
public void start(T args);
public void doWork();
public void end();
}
您可以像这样定义接口
interface IWorkflow<T extends IWorkflowStartArgs>
{
public void start(T args);
public void doWork();
public void end();
}
java不会认为它是特定的实现类型。 考虑下面的情况,您可以看到问题发生的地方(如果函数参数中实现的类的自动映射可用java来表示):
解决方案? 如@sanbhat所示,使用泛型 或者如果你不想研究泛型, 然后我想你应该通过一个IWorkflowStartArgs然后像你说的那样投进去, 这样说:public class CoffeeWorkflow implements IWorkflow
{
public void start(IWorkflowStartArgs args)
{
if (args instanceof CoffeeWorkflowStartArgs) {
CoffeeWorkflowStartArgs coffeeArgs = (CoffeeWorkflowStartArgs) args;
// ....
}
}
// ....
}
假设您有另一个类似的类,
然后再次需要检查instanceof
。
这就是主要引入泛型的原因-避免通过instanceof
重复检查;
作为类似模式类的“强”>一般/强>模型。 java不会考虑它作为具体的实现类型。 考虑下面的情况,您可以看到问题发生的地方(如果函数参数中实现的类的自动映射可用java来表示): 解决方案? 如@sanbhat所示,使用泛型 或者如果你不想研究泛型, 然后我想你应该通过一个IWorkflowStartArgs然后像你说的那样投进去, 这样说:
public class CoffeeWorkflow implements IWorkflow
{
public void start(IWorkflowStartArgs args)
{
if (args instanceof CoffeeWorkflowStartArgs) {
CoffeeWorkflowStartArgs coffeeArgs = (CoffeeWorkflowStartArgs) args;
// ....
}
}
// ....
}
假设您有另一个类似的类,
然后再次需要检查instanceof
。
这就是主要引入泛型的原因-避免通过instanceof
重复检查;
并作为类似模式类的通用模型。有一种使用单个通用参数的解决方案,可确保类型安全。让我们为其使用通用参数WorkflowType:
interface IWorkflow<T extends WorkflowType>
{
public void start(IWorkflowStartArgs<T> args);
public void doWork(IWorkflowWorkArgs<T> args);
public void end(IWorkflowEndArgs<T> args);
}
您的咖啡工作流如下所示:
public class Coffee implements IWorkflow<CoffeeWorkflowType> {
{
public void start(IWorkflowStartArgs<CoffeeWorkflowType> args);
public void doWork(IWorkflowWorkArgs<CoffeeWorkflowType> args);
public void end(IWorkflowEndArgs<CoffeeWorkflowType> args);
}
公共类Coffee实现了IWorkflow{
{
公共无效启动(IWorkflowStartArgs参数);
公共无效doWork(IWorkflowWorkArgs args args);
公共void end(IWorkflowEndArgs args args);
}
以及工作流参数的实现:
public class CoffeeWorkflowStartArgs implements IWorkflowStartArgs<CoffeeWorkflowType> { ... }
public class CoffeeWorkflowWorkArgs implements IWorkflowWorkArgs<CoffeeWorkflowType> { ... }
public class CoffeeWorkflowEndArgs implements IWorkflowEndArgs<CoffeeWorkflowType> { ... }
公共类CoffeeWorkflowStartArgs实现IWorkflowStartArgs{…}
公共类CoffeeWorkflowWorkArgs实现IWorkflowWorkArgs{…}
公共类CoffeeWorkflowEndArgs实现IWorkflowEndArgs{…}
有一种解决方案使用一个通用参数来确保类型安全。让我们使用通用参数WorkflowType:
interface IWorkflow<T extends WorkflowType>
{
public void start(IWorkflowStartArgs<T> args);
public void doWork(IWorkflowWorkArgs<T> args);
public void end(IWorkflowEndArgs<T> args);
}
您的咖啡工作流如下所示:
public class Coffee implements IWorkflow<CoffeeWorkflowType> {
{
public void start(IWorkflowStartArgs<CoffeeWorkflowType> args);
public void doWork(IWorkflowWorkArgs<CoffeeWorkflowType> args);
public void end(IWorkflowEndArgs<CoffeeWorkflowType> args);
}
公共类Coffee实现了IWorkflow{
{
公共无效启动(IWorkflowStarTargets args);
公共无效doWork(IWorkflowWorkArgs args args);
公共void end(IWorkflowEndArgs args args);
}
以及工作流参数的实现:
public class CoffeeWorkflowStartArgs implements IWorkflowStartArgs<CoffeeWorkflowType> { ... }
public class CoffeeWorkflowWorkArgs implements IWorkflowWorkArgs<CoffeeWorkflowType> { ... }
public class CoffeeWorkflowEndArgs implements IWorkflowEndArgs<CoffeeWorkflowType> { ... }
公共类CoffeeWorkflowStartArgs实现IWorkflowStartArgs{…}
公共类CoffeeWorkflowWorkArgs实现IWorkflowWorkArgs{…}
公共类CoffeeWorkflowEndArgs实现IWorkflowEndArgs{…}
听起来很有趣。我是否应该扩展它以适用于所有参数,因为我希望在doWork()
和end()
,也要扩展它?是丑陋的,但坚持你想要的:(我如何建模,所以它不丑?听起来很有趣。我是否应该扩展它,因为我想在doWork()
和end()中扩展这些参数吗
?是的,丑陋,但坚持你想要的:(我如何建模,这样它就不难看了?所以我的选择是:拥有一个大的通用工作流或检查每个方法。两者似乎都不是很好。使用泛型会更好。一开始似乎很难,但一旦掌握好了,泛型通常会减少代码大小。接口IWorkflow{…}泛型只在声明类型变量时看起来很长。Rest变得太方便了。你是对的。开始使用它后,感觉有些自然,但一开始看起来很难看。所以我的选择是:拥有一个大的泛型工作流或检查每个方法。两者似乎都不是很好。使用泛型会更好。一开始似乎很难,但一旦你掌握了一个好的抓地力,泛型通常会减少你的代码大小泛型只在声明类型变量时看起来很长。Rest变得太方便了。你是对的。开始使用泛型后,感觉有点自然,但一开始看起来很难看。太棒了。对此,你得想一想,但已经很喜欢了。public void start(CoffeeWorkflowStartArgs args)部分似乎不起作用。它未被识别为重写,我将不得不使用泛型参数实现另一个重写。好的,我自己测试过它,编写Coffee实现时出错。这些方法需要使用IWorkflowStartArgs
而不是最终实现CoffeeWorkflowStartArgs
(代码>工作和End
)也是如此。我更新了答案。太好了。必须考虑一下,但已经像它一样了public void start(CoffeeWorkflowStarTargets args args)
部分似乎不起作用。它未被识别为重写,我将不得不使用泛型参数实现另一个重写。好的,我自己测试过它,编写Coffee实现时出错。这些方法需要使用IWorkflowStartArgs
而不是最终实现CoffeeWorkflowStartArgs
(同样适用于工作
和结束
),我已经更新了答案。