2010-05-18 14 views
33

que tienen una interfaz:cruce de clase de interfaz como parámetro en Java

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 como

foo.sendNotification(Email.class); 

pero me siguen dando una excepción diciendo:

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

En caso de que no este trabajo si se interconecta esa clase?

+1

¿Qué es la clase EmailNotification y qué implementa o amplía? –

+0

¿Realmente desea pasar el objeto Clase, no una instancia de alguna clase que implemente la interfaz IMech? Eso ciertamente puede ser lo que quieras, pero no puedo decir a partir de la información que proporcionaste ya sea intencional o un error de diseño. –

+0

Disculpa, acorté algunos nombres de clase ... EmailNotification es la clase de correo electrónico – aleclerc

Respuesta

48

Tal vez usted necesita

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

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 en lugar de superextends ... déjame Consult Generics chapter ...

Editar Effective Java: Effective Java dice:

Aquí es una regla mnemotécnica para ayudarle a recordar qué tipo comodín para utilizar: PECS significa productor-se extiende, los consumidores-sup er.

Asumo este estará produciendo casos IMECH, y que extends es correcta.

10

Debido a que las dos clases Class<IMechanism> y Class<EmailNotification> mismos son no relacionados por sucesiones, a pesar de que IMechanism y EmailNotificationson.

Necesita hacer que su método acepte Class<? extends IMechanism>.

1

La idea detrás de las interfaces es que no necesita saber cuál es. Simplemente debería poder pasar un mensaje 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 de una interfaz. Si solo lo está utilizando para una opción, quizás deba considerar el uso de una enumeración.

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 estas no responden directamente a sus preguntas, pero éstas son las formas típicas de uso, y por lo general son indicativos de los patrones de diseño más adaptables. Después de todo, ¿realmente necesitas enviar un objeto de clase? Una enumeración parece más apropiada si simplemente estás determinando qué mecanismo usar.

5

Su mecanismo de parámetro tiene que utilizar un comodín acotada, así:

SendNotification public void (Clase < extiende IMECH> mecanismo?) { }

Citando al genéricos tutorial link text

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

3

la forma correcta es:

public void sendNotification(IMech mechanism) { 

} 

así que por favor leer algunos tutoriales de java sobre interfaces de todos!

1

OMI sería más limpio si usted hace esto:

public void sendNotification(IMech mechanism){ 
} 

siempre se puede obtener la clase dentro del método.

Cuestiones relacionadas