7

我有一个超类的方法:

protected <E extends Enum<E>,T extends VO> void processarRelatorioComEstado(Date dataInicial, Date dataFinal, E estado) throws RelatorioException {

    throw new UnsupportedOperationException("method not overridden");
}

在它的一个子类中,我想做以下事情:

    @Override
protected <E extends Enum<E>> DemonstrativoReceitaDespesasAnexo12Vo processarRelatorioComEstado(Date dataInicial, Date dataFinal, E estado) throws RelatorioException {
//do something
return DemonstrativoReceitaDespesasAnexo12Vo;
}

但这只是行不通。问题是我有一个超类的引用,我想调用这个方法,但只能在其中一个子类中调用。

4

3 回答 3

7

根据java覆盖

覆盖方法与它覆盖的方法具有相同的名称、参数数量和类型以及返回类型。覆盖方法还可以返回被覆盖方法返回的类型的子类型。这称为协变返回类型。

在这里,您的方法返回类型不同,因此它不会被覆盖。

于 2013-09-12T20:35:49.083 回答
4

您不能更改重写方法中类型参数的数量。至于您的情况,覆盖显然会因返回类型而失败。但是即使返回类型相同,您的方法仍然不会被等效覆盖,因为您在应该被覆盖的方法中的类型参数较少。

来自JLS - 方法签名

如果两个方法具有相同的名称和参数类型,则它们具有相同的签名。

如果满足以下所有条件,则两个方法或构造函数声明 M 和 N 具有相同的参数类型:

  • 它们具有相同数量的形式参数(可能为零)
  • 它们具有相同数量的类型参数(可能为零)

因此,即使以下代码也会失败:

interface Demo {
    public <S, T> void show();
}

class DemoImpl implements Demo {
    @Override
    public <T> void show() { }  // Compiler error
}

由于show()类型参数较少,类中的方法与接口中的方法不等效。

因此,您应该确保方法签名与该 JLS 部分中指定的完全相同(相同名称、相同数量和类型的参数(包括类型参数)、协变返回类型)。

于 2013-09-12T20:46:42.603 回答
1

阅读上面的评论,我知道该方法行不通,因此我对代码进行了一些更改并像魅力一样工作,遵循代码:

超类:

protected VO processarRelatorioComEstado(Date dataInicial, Date dataFinal, Enum<?> estado) throws RelatorioException {

    throw new UnsupportedOperationException("method not overridden");
}

和子类:

public VO processarRelatorioComEstado(Date dataInicial, Date dataFinal, Enum<?> estado) throws RelatorioException {
//do something
return VOsubtype;

}

多谢你们。

于 2013-09-13T11:51:10.880 回答