Reputation: 562
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;
}
}
Compilator is complaining: The method setHeader(Header) of type AProcessor must override or implement a supertype method
Edit:
Thanks. I got confused because I wanted multiple methods with different types.
Now I realized a can add as many parametrized types as I want in class level. Like FileProcessor<T, F, M>
.
Upvotes: 4
Views: 1016
Reputation: 63814
I think you wanna 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;
}
}
Upvotes: 3
Reputation: 19185
The signature of a method m1 is a subsignature of the signature of a method m2 if either:
m2 has the same signature as m1, or
the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
In your case as erasure
is different ie. in once case you have and and in the implementing class you don't have.
Because raw types are allowed to override generic method below can work in your case.
@Override
public Object setHeader(Object header) {
return null;
}
Also if you change your declaration like below
public interface FileProccessor<T> {
public T setHeader(T header);
}
You can override method based on Type passed in FileProccessor<T>
in the child class while extending
public class AProcessor implements FileProccessor<Header> {
@Override
public Header setHeader(Header header) {
return null;
}
}
Upvotes: 0
Reputation: 7197
You cannot override a method this way. AProcessor
must 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 which concrete class is used, and it doesn't with your AProcessor
. Therefore it makes sense that the type checker rejects it.
Something like this would work (since the FileProcessor interface is now parameterized with 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 user of the class would have to write:
FileProcessor<Header> f = new AProcessor();
and the argument to setHeader
must be of type Header
...
Upvotes: 0
Reputation: 727137
Your interface declaration specifies that all implementations of the interface will provide a generic method with this signature:
public <RT> RT setHeader(RT header);
In other words, the caller would be able to pass an object of any type, and get back an object of the same exact type.
You implementation declaration, on the other hand, limits the user to a single type, i.e. the Header
. That's why the compiler is complaining about inability to override.
The trick would work if the interface were generic, and a type implementing it was implementing a generic instance, like this:
public interface FileProccessor<T> {
public T setHeader(T header);
}
public class AProcessor implements FileProccessor<Header> {
}
Upvotes: 4
Reputation: 207026
Try defining your interface like this:
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;
}
}
Upvotes: 1