0

第一个版本:

public interface DeepCopyable<T>
{
  T deepCopy();
}

public interface Statement extends DeepCopyable<Statement>
{
}

public interface Expression
{
  Expression deepCopy(); // forgot I have an interface for this
}

public class Invocation implements Expression, Statement
{
  public final String Field;

  public Invocation(String field)
  {
    Field = field;
  }

  public Invocation deepCopy()
  {
    return new Invocation(Field);
  }
}

第二版,更新表达式接口:

public interface Expression extends DeepCopyable<Expression>
{
}

但现在我得到编译错误

Error: C:\temp\Invocation.java:1: DeepCopyable cannot be inherited with different arguments: <Expression> and <Statement>

在返回类型不变的一般情况下,我可以理解此错误消息;但是,如果我两次使用返回类型 A 和 B 继承相同的接口,并且进一步,实现方法返回 C,其中 C 与 A 和 B 是协变的,这不应该是安全的吗?

4

2 回答 2

0

在 Invocation 类中,您正在扩展两个接口 Expression 和 Statement,在您的代码的第二个版本中,您的 Expression 接口正在扩展 DeepcCopyable 接口,如下所示。

class Invocation implements Expression, Statement {...}




interface Statement extends DeepCopyable<Statement> {
}

interface Expression extends DeepCopyable<Expression> {
}

在您的代码中,当您实现扩展到不同泛型的两个接口 Expression 和 Statement 时会发生什么,这里发生的情况是编译器对要考虑的内容感到困惑,因此它不允许您同时实现接口 Expression、Statement班级。

于 2012-12-23T08:01:00.570 回答
0

您不能使用不同的参数两次实现一个接口。这就是第二个版本的问题。

第一个版本的问题是它的两个接口都指定deepCopy了稍微不同的签名。但是,它实现的签名与它们都兼容,因此没有问题。

于 2012-12-23T20:56:49.257 回答