Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding a method with Generic Parameters in Java?

I have an abstract Class Monitor.java which is subclassed by a Class EmailMonitor.java.

The method:

public abstract List<? extends MonitorAccount> performMonitor(List<? extends MonitorAccount> accounts) 

is defined in Monitor.java and must be overridden in EmailMonitor.java.

I currently have the method overridden in EmailMonitor.java as follows:

@Override public List<EmailAccount> performMonitor(List<EmailAccount> emailAccounts) {     //...unrelated logic     return emailAccounts; } 

However, this produces the compile time error:

Name clash: The method performMonitor(List<EmailAccount>) of type EmailMonitor has the same erasure as performMonitor(Lis<? extends MonitorAccount> emailAccounts) of type Monitor but does not override it

EmailAccount is a subclass of MonitorAccount, so (in my mind at least) overriding it in this way makes perfect sense. Seeing as the compiler is not happy with my logic though, How should I go about this correctly while still keeping my compile time checks to make sure that all calls to EmailMonitor.performMonitor() receive Lists of EmailAccount rather than some other type of MonitorAccount?

like image 962
Robert Ngetich Avatar asked Oct 27 '08 11:10

Robert Ngetich


People also ask

Can you override a method with different parameters Java?

No, while overriding a method of the super class we need to make sure that both methods have same name, same parameters and, same return type else they both will be treated as different methods.

Can override method have different parameters?

The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.

What is a generic parameter in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

What are the rules for overriding a method in Java?

Instance methods can be overridden only if they are inherited by the subclass. A method declared final cannot be overridden. A method declared static cannot be overridden but can be re-declared. If a method cannot be inherited, then it cannot be overridden.


1 Answers

No, it's not overriding it properly. Overriding means you should be able to cope with any valid input to the base class. Consider what would happen if a client did this:

Monitor x = new EmailMonitor(); List<NonEmailAccount> nonEmailAccounts = ...; x.performMonitor(nonEmailAccounts); 

There's nothing in there which should give a compile-time error given your description - but it's clearly wrong.

It sounds to me like Monitor should be generic in the type of account it can monitor, so your EmailMonitor should extend Monitor<EmailAccount>. So:

public abtract class Monitor<T extends MonitorAccount> {     ...     public abstract List<? extends T> performMonitor(         List<? extends T> accounts); }  public class EmailMonitor extends Monitor<EmailAccount> {     @Override     public abstract List<? extends EmailAccount> performMonitor(         List<? extends EmailAccount> accounts)     {         // Code goes here     } } 

You might want to think carefully about the generics in the performMonitor call though - what's the return value meant to signify?

like image 79
Jon Skeet Avatar answered Oct 01 '22 10:10

Jon Skeet