Reputation: 707
I have an interface:
public interface IMech {
}
and a class that implements it
public class Email implements IMech {
}
and a third class that has this method implemented:
public void sendNotification( Class< IMech > mechanism ){
}
now I'm trying to call that method like so
foo.sendNotification(Email.class);
but i keep getting an exception saying:
The method sendNotification(Class<IMech>) in the type RemediationOperator is not applicable for the arguments (Class<Email>)
Shouldn't this work if it interfaces that class?
Upvotes: 39
Views: 59275
Reputation: 41097
IMO it would be cleaner if you do this :
public void sendNotification( IMech mechanism ){
}
You can always get the class inside the method.
Upvotes: 1
Reputation: 39
the correct way is:
public void sendNotification(IMech mechanism) {
}
so please read some java tutorials about interfaces everyone!
Upvotes: 3
Reputation: 88796
Generics don't work that way in Java. What you really need to do it change the method signature to
public void sendNotification( Class< ? extends IMech > mechanism ){
}
Or is that super
instead of extends
... let me consult Effective Java's Generics chapter...
Edit: Effective Java says:
Here is a mnemonic to help you remember which wildcard type to use: PECS stands for producer-extends, consumer-super.
I'm assuming this will be producing IMech instances, and that extends
is correct.
Upvotes: 3
Reputation: 89
Your parameter mechanism needs to use a bounded wildcard, like so:
public void sendNotification( Class< ? extends IMech > mechanism ){ }
Quoting the generics tutorial link text
In general, if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G is a subtype of G.
Upvotes: 5
Reputation: 82559
The idea behind interfaces is that you don't need to know which one it is. You should simply be able to pass in an IMech and call its functionality regardless of implementation. Consider the following:
public interface IMech {
void sendMessage();
}
public class Email implements IMech {
@Override
void sendMessage() { /* stuff here to send email */ }
}
That's the typical usage pattern for an interface. If you're only using it for an option, perhaps you should consider using an enum instead.
enum IMech { EMAIL, INSTANT_MESSAGE, SNAIL_MAIL, YELL_OVER_CUBICLE }
public void sendNotification( IMech mechanism ){
switch(mechanism) {
case IMech.EMAIL: // do email .. etc
}
}
foo.sendNotification(IMech.EMAIL);
Now I know these don't directly answer your questions, but these are the typical forms of usage, and are usually indicative of more adaptable design patterns. After all, do you really need to send in a class object? An enum seems more appropriate if you're merely determining which mechanism to use.
Upvotes: 1
Reputation: 8642
Because the two classes Class<IMechanism>
and Class<EmailNotification>
themselves are not related by inheritence, even though IMechanism
and EmailNotification
are.
You need to make your method accept a Class<? extends IMechanism>
.
Upvotes: 10
Reputation: 242686
Perhaps you need
public void sendNotification( Class<? extends IMech> mechanism ) {
Upvotes: 56