Generics java implements interface

What is wrong with this code?

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

The compiler complains: the setHeader method (Header) of type AProcessor must override or implement the supertype method

Edit: Thank you. I am confused because I need several methods with different types. Now I realized that you can add as many parameterized types as I want at the class level. Like FileProcessor<T, F, M> .

+4
source share
5 answers

The interface declaration states that all implementations of the interface will provide a common method with this signature:

 public <RT> RT setHeader(RT header); 

In other words, the caller can pass an object of any type and return an object of the same exact type.

On the other hand, you declare the implementation by restricting the user to one type, i.e. Header . Therefore, the compiler complains about the inability to override.

The trick will work if the interface is shared and the type that implements it implements a shared instance, for example:

 public interface FileProccessor<T> { public T setHeader(T header); } public class AProcessor implements FileProccessor<Header> { } 
+4
source

I think you want to do this:

 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; } } 
+3
source

Try defining your interface as follows:

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

And then implement it like this:

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

You cannot override a method this way. AProcessor should be able to accept everything that FileProcessor accepts as input to setHeader . Consider this code:

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

This code should work no matter what particular class is used, and not with your AProcessor . Therefore, it makes sense that the test type rejects it.

Something like this will work (since the FileProcessor interface is now parameterized by RT):

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

Now the class user will need to write:

 FileProcessor<Header> f = new AProcessor(); 

and the setHeader argument must be of type Header ...

0
source

JLS # 8.4.2. Method signature

The signature of method m1 is a signature of the signature of m2 if:

  • m2 has the same signature as m1, or

  • signature m1 is the same as erasing (section 4.6) signature m2.

In your case, when erasure is different, i.e. in one case, you have in the implementation class that you donโ€™t have.

Since in your case you can work with raw types to override the general method .

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

Also, if you change your ad as shown below

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

You can override a method based on the type passed to FileProccessor<T> in the child class with extension

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

Source: https://habr.com/ru/post/1436778/


All Articles