Ответ 1
Возможно, вам нужно
public void sendNotification( Class<? extends IMech> mechanism ) {
У меня есть интерфейс:
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>)
Не следует ли это работать, если он взаимодействует с этим классом?
Возможно, вам нужно
public void sendNotification( Class<? extends IMech> mechanism ) {
Поскольку два класса Class<IMechanism>
и Class<EmailNotification>
сами не связаны с наследованием, хотя IMechanism
и EmailNotification
.
Вам нужно, чтобы ваш метод принял Class<? extends IMechanism>
.
Ваш механизм параметров должен использовать ограниченный шаблон, например:
public void sendNotification (механизм класса <? extends IMech > ) { }
Цитирование учебника generics текст ссылки
В общем случае, если Foo является подтипом (подкласса или субтерминала) Бар, и G - это объявление общего типа, оно это не тот случай, когда G является подтип G.
Generics не работают таким образом в Java. Что вам действительно нужно сделать, чтобы изменить подпись метода на
public void sendNotification( Class< ? extends IMech > mechanism ){
}
Или это super
вместо extends
... позвольте мне проконсультироваться с эффективным Java глава Generics...
Изменить: Эффективная Java говорит:
Вот мнемоника, которая поможет вам помните, какой тип шаблона использовать: PECS означает продюсер-продюсеры, потребитель-супер.
Я предполагаю, что это будет производить экземпляры IMech и что extends
верен.
правильный путь:
public void sendNotification(IMech mechanism) {
}
поэтому, пожалуйста, прочитайте несколько обучающих программ java об интерфейсах каждый!
Идея интерфейсов заключается в том, что вам не нужно знать, какой именно. Вы должны просто передать 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);
Теперь я знаю, что они прямо не отвечают на ваши вопросы, но это типичные формы использования и обычно указывают на более адаптируемые шаблоны проектирования. В конце концов, действительно ли вам нужно отправить объект класса? Перечисление представляется более подходящим, если вы просто определяете, какой механизм использовать.
ИМО было бы чище, если вы это сделаете:
public void sendNotification( IMech mechanism ){
}
Вы всегда можете получить класс внутри метода.