java方法泛型实现接口

时间:2012-09-28 10:00:42

标签: java generics

此代码有什么问题?

public interface FileProccessor {
    public <RT> RT setHeader(RT header);
}

public class AProcessor implements FileProccessor {

    @Override
    public Header setHeader(Header header) {
        return null;
    }
}

Compilator抱怨: AProcessor类型的方法setHeader(Header)必须覆盖或实现超类型方法

修改 谢谢。我感到困惑,因为我想要多种不同类型的方法。 现在我意识到可以在类级别添加任意数量的参数化类型。与FileProcessor<T, F, M>一样。

5 个答案:

答案 0 :(得分:4)

您的接口声明指定接口的所有实现都将提供带有此签名的通用方法:

public <RT> RT setHeader(RT header);

换句话说,调用者将能够传递任何类型的对象,并获得相同类型的对象。

另一方面,您的实现声明将用户限制为单一类型,即Header。这就是编译器抱怨无法覆盖的原因。

如果接口是通用的,那么技巧就可以工作,实现它的类型实现了一个通用实例,如下所示:

public interface FileProccessor<T> {
    public T setHeader(T header);
}

public class AProcessor implements FileProccessor<Header> {
}

答案 1 :(得分:3)

我想你想这样做:

public interface FileProccessor<RT, RX> {
    public RT setHeader(RT header);
    public RX setFooter(RX footer);
}

public class AProcessor implements FileProccessor<Header, Footer> {

    @Override
    public Header setHeader(Header header) {
        return null;
    }

    @Override
    public Footer setFooter(Footer footer) {
        return null;
    }
}

答案 2 :(得分:1)

尝试定义您的界面:

public interface FileProccessor<RT> {
    public RT setHeader(RT header);
}

然后像这样实现:

public class AProcessor implements FileProccessor<Header> {
    @Override
    public Header setHeader(Header header) {
        return null;
    }
}

答案 3 :(得分:0)

您不能以这种方式覆盖方法。 AProcessor必须能够接受FileProcessor接受setHeader作为输入的所有内容。请考虑以下代码:

FileProcessor f = new AProcessor();
String s =  f.setHeader("Bah");

无论使用哪个具体类,此代码都应该有效,而且不适用于AProcessor。因此,类型检查器拒绝它是有道理的。

这样的东西会起作用(因为FileProcessor接口现在用RT参数化):

public interface FileProccessor<RT> {
    public RT setHeader(RT header);
}

public class AProcessor implements FileProccessor<Header> {

    @Override
    public Header setHeader(Header header) {
        return null;
    }
}

现在该类的用户必须写:

FileProcessor<Header> f = new AProcessor();

setHeader的参数必须为Header ...

类型

答案 4 :(得分:0)

JLS # 8.4.2. Method Signature

  

方法m1的签名是方法m2的签名的子签名,如果:

     
      
  • m2与m1具有相同的签名,或

  •   
  • m1的签名与删除(§4.6)相同   签名为m2。

  •   

在你的情况下erasure是不同的,即。在你曾经拥有的情况下,并且在实施课程中你没有。

因为允许原始类型覆盖通用方法,所以可以适用于您的情况。

    @Override
    public Object setHeader(Object header) {
        return null;
    }

此外,如果您更改下面的声明

 public interface FileProccessor<T> {
    public T setHeader(T header);
 }

您可以在扩展

时基于子类中FileProccessor<T>中传递的类型覆盖方法
public class AProcessor implements FileProccessor<Header> {
    @Override
    public Header setHeader(Header header) {
        return null;
    }
}