Pasar la Clase de Interfaz como Parámetro en Java


Tengo una interfaz:

public interface IMech {

}

Y una clase que lo implementa

public class Email implements IMech {

}

Y una tercera clase que tiene este método implementado:

public void sendNotification( Class< IMech > mechanism ){
}

Ahora estoy tratando de llamar a ese método así

foo.sendNotification(Email.class);

, Pero sigo recibiendo una excepción diciendo:

The method sendNotification(Class<IMech>) in the type RemediationOperator is not applicable for the arguments (Class<Email>)

¿No debería funcionar esto si interfiere con esa clase?

Author: Jarl, 2010-05-18

7 answers

Tal vez necesites

public void sendNotification( Class<? extends IMech> mechanism ) { 
 48
Author: axtavt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-18 17:45:15

Porque las dos clases Class<IMechanism> y Class<EmailNotification> ellos mismos son no relacionados por herencia, a pesar de que IMechanism y EmailNotification are .

Necesitas hacer que tu método acepte un Class<? extends IMechanism>.

 10
Author: Mike Daniels,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-18 17:46:47

Su mecanismo de parámetros necesita usar un comodín acotado, así:

Public void SendNotification (Class mecanismo ){ }

Citando el tutorial de genéricos texto de enlace

En general, si Foo es un subtipo (subclase o subinterface) de Bar, y G es una declaración de tipo genérico, se no es el caso de que G es a subtipo de G.

 5
Author: rwhit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-18 17:49:52

Los genéricos no funcionan de esa manera en Java. Lo que realmente necesita hacer es cambiar la firma del método a

public void sendNotification( Class< ? extends IMech > mechanism ){
}

O es que super en lugar de extends... déjame consultar el capítulo de Genéricos de Effective Java ...

Editar: Java eficaz dice:

Aquí hay una mnemotécnica para ayudarte recordar qué tipo de comodín usar: PECS significa producer-extends, consumer-super.

Asumo que esto producirá instancias IMech, y que {[2] } es correcto.

 3
Author: Powerlord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-18 17:52:31

La forma correcta es:

public void sendNotification(IMech mechanism) {

}

Así que por favor lea algunos tutoriales de Java sobre interfaces de todo el mundo!

 3
Author: chandler newman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-22 06:47:21

La idea detrás de las interfaces es que no necesita saber cuál es. Simplemente debe ser capaz de pasar un IMech y llamar a su funcionalidad independientemente de la implementación. Considere lo siguiente:

public interface IMech {
    void sendMessage();
}

public class Email implements IMech {
    @Override
    void sendMessage() { /* stuff here to send email */ }
}

Ese es el patrón de uso típico para una interfaz. Si solo lo estás usando para una opción, tal vez deberías considerar usar una enumeración en su lugar.

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);

Ahora sé que estos no responden directamente a sus preguntas, pero estas son las formas típicas de uso, y generalmente son indicativo de patrones de diseño más adaptables. Después de todo, ¿realmente necesita enviar un objeto de clase? Una enumeración parece más apropiada si simplemente estás determinando qué mecanismo usar.

 1
Author: corsiKa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-18 17:47:43

IMO sería más limpio si haces esto:

public void sendNotification( IMech mechanism ){
}

Siempre puede obtener la clase dentro del método.

 1
Author: fastcodejava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-22 07:07:03