Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.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协方差_Java_Interface_Covariance - Fatal编程技术网

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
(同样适用于
工作
结束
),我已经更新了答案。