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
?
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.
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.
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.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With