Подтвердить что ты не робот

Передача класса интерфейса в качестве параметра в Java

У меня есть интерфейс:

public interface IMech {

}

и класс, который его реализует

public class Email implements IMech {

}

и третий класс, который реализовал этот метод:

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

теперь я пытаюсь вызвать этот метод так

foo.sendNotification(Email.class);

но я продолжаю получать исключение, говоря:

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

Не следует ли это работать, если он взаимодействует с этим классом?

4b9b3361

Ответ 1

Возможно, вам нужно

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

Ответ 2

Поскольку два класса Class<IMechanism> и Class<EmailNotification> сами не связаны с наследованием, хотя IMechanism и EmailNotification .

Вам нужно, чтобы ваш метод принял Class<? extends IMechanism>.

Ответ 3

Ваш механизм параметров должен использовать ограниченный шаблон, например:

public void sendNotification (механизм класса <? extends IMech > ) { }

Цитирование учебника generics текст ссылки

В общем случае, если Foo является подтипом (подкласса или субтерминала) Бар, и G - это объявление общего типа, оно это не тот случай, когда G является подтип G.

Ответ 4

Generics не работают таким образом в Java. Что вам действительно нужно сделать, чтобы изменить подпись метода на

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

Или это super вместо extends... позвольте мне проконсультироваться с эффективным Java глава Generics...

Изменить: Эффективная Java говорит:

Вот мнемоника, которая поможет вам помните, какой тип шаблона использовать: PECS означает продюсер-продюсеры, потребитель-супер.

Я предполагаю, что это будет производить экземпляры IMech и что extends верен.

Ответ 5

правильный путь:

public void sendNotification(IMech mechanism) {

}

поэтому, пожалуйста, прочитайте несколько обучающих программ java об интерфейсах каждый!

Ответ 6

Идея интерфейсов заключается в том, что вам не нужно знать, какой именно. Вы должны просто передать IMech и вызвать его функциональность независимо от ее реализации. Рассмотрим следующее:

public interface IMech {
    void sendMessage();
}

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

Это типичный шаблон использования для интерфейса. Если вы используете его только для опции, возможно, вам стоит подумать об использовании перечисления.

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

Теперь я знаю, что они прямо не отвечают на ваши вопросы, но это типичные формы использования и обычно указывают на более адаптируемые шаблоны проектирования. В конце концов, действительно ли вам нужно отправить объект класса? Перечисление представляется более подходящим, если вы просто определяете, какой механизм использовать.

Ответ 7

ИМО было бы чище, если вы это сделаете:

public void sendNotification( IMech mechanism ){
}

Вы всегда можете получить класс внутри метода.