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?

33
demandé sur Jarl 2010-05-18 21:35:21

7 réponses

Peut-être avez-vous besoin de

public void sendNotification( Class<? extends IMech> mechanism ) { 
48
répondu axtavt 2010-05-18 17:45:15

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

10
répondu Mike Daniels 2010-05-18 17:46:47

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.

5
répondu rwhit 2010-05-18 17:49:52

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.

3
répondu Powerlord 2010-05-18 17:52:31

La manière correcte est:

public void sendNotification(IMech mechanism) {

}

Veuillez donc lire quelques tutoriels java sur les interfaces tout le monde!

3
répondu chandler newman 2012-09-22 06:47:21

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.

1
répondu corsiKa 2010-05-18 17:47:43

IMO ce serait plus propre si vous faites ceci:

public void sendNotification( IMech mechanism ){
}

Vous pouvez toujours obtenir la classe dans la méthode.

1
répondu fastcodejava 2012-09-22 07:07:03