4

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>.

2
  • Try adding the generic to the FileProcessor, like FileProcessor<RT> and implement it with ... implements FileProcessor<Header>. Commented Sep 28, 2012 at 10:02
  • The error is, because it's not overriding. How do you relate RT and Header? Commented Sep 28, 2012 at 10:02

5 Answers 5

4

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> {
}
Sign up to request clarification or add additional context in comments.

Comments

3

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;
    }
}

2 Comments

No I don't actually, I want multiple generic methods, hmmm, not sure if this is possible though.
You could add another method to this. I updated my answer and added a second one.
1

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;
    }
}

Comments

0

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...

Comments

0

JLS # 8.4.2. Method Signature

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;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.