Passage de la classe D'Interface en tant que paramètre en Java
J'ai une interface:
public interface IMech {
}
, Et une classe qui l'implémente
public class Email implements IMech {
}
Et une troisième classe qui a cette méthode implémentée:
public void sendNotification( Class< IMech > mechanism ){
}
Maintenant, j'essaie d'appeler cette méthode comme ceci
foo.sendNotification(Email.class);
Mais je continue à avoir une exception disant:
The method sendNotification(Class<IMech>) in the type RemediationOperator is not applicable for the arguments (Class<Email>)
Cela ne devrait-il pas fonctionner s'il Interface cette classe?
7 réponses
Peut-être avez-vous besoin de
public void sendNotification( Class<? extends IMech> mechanism ) {
, Car les deux classes Class<IMechanism>
et Class<EmailNotification>
eux-mêmes sont pas liées par l'héritage, même si IMechanism
et EmailNotification
sont.
Vous devez faire en sorte que votre méthode accepte un Class<? extends IMechanism>
.
Votre mécanisme de paramètre doit utiliser un caractère générique délimité, comme ceci:
Public void sendNotification( Classe mécanisme ){ }
Citant les génériques tutoriel texte du lien
En général, si Foo est un sous-type (sous-classe ou sous-interface) de Bar, et G est une déclaration de type générique, il n'est pas le cas que G est sous-type de G.
Les génériques ne fonctionnent pas de cette façon en Java. Ce que vous devez vraiment faire changer la signature de la méthode en
public void sendNotification( Class< ? extends IMech > mechanism ){
}
Ou super
au lieu de extends
... permettez-moi de consulter le chapitre Generics de Java...
Modifier: Java efficace dit:
Voici un mnémonique pour vous aider rappelez-vous quel type générique utiliser: PECS signifie producteur-étend, consommateur-super.
Je suppose que cela produira des instances IMech, et que extends
est correct.
La manière correcte est:
public void sendNotification(IMech mechanism) {
}
Veuillez donc lire quelques tutoriels java sur les interfaces tout le monde!
L'idée derrière les interfaces est que vous n'avez pas besoin de savoir lequel c'est. Vous devriez simplement être capable de transmettre un IMech et d'appeler sa fonctionnalité indépendamment de l'implémentation. Considérez ce qui suit:
public interface IMech {
void sendMessage();
}
public class Email implements IMech {
@Override
void sendMessage() { /* stuff here to send email */ }
}
C'est le modèle d'utilisation typique d'une interface. Si vous ne l'utilisez que pour une option, vous devriez peut-être envisager d'utiliser une énumération à la place.
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);
Maintenant, je sais que ceux-ci ne répondent pas directement à vos questions, mais ce sont les formes typiques d'utilisation, et sont généralement indicatif de modèles de conception plus adaptables. Après tout, avez-vous vraiment besoin d'envoyer un objet de classe? Une énumération semble plus appropriée si vous déterminez simplement quel mécanisme utiliser.
IMO ce serait plus propre si vous faites ceci:
public void sendNotification( IMech mechanism ){
}
Vous pouvez toujours obtenir la classe dans la méthode.