在Java中将接口类作为参数传递

38

我有一个接口:

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

如果它与那个类接口,这样难道不应该可以工作吗?


1
EmailNotification类是什么,它实现或扩展了什么? - Amir Afghani
你真的想传递Class对象,而不是实现IMech接口的某个类的实例吗?这可能是你想要的,但我无法从你提供的信息中确定它是否是有意为之还是设计错误。 - Stephen P
抱歉,我缩短了一些类的名称...EmailNotification 是 Email 类。 - aleclerc
7个回答

55
也许你需要。
public void sendNotification( Class<? extends IMech> mechanism ) { 

10

由于两个类 Class<IMechanism>Class<EmailNotification> 本身不是通过继承相关联的,尽管 IMechanismEmailNotification 是相关联的。

你需要使你的方法接受一个 Class<? extends IMechanism>


5
您的参数机制需要使用有界通配符,如下所示:

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

引用泛型教程链接文本

一般情况下,如果Foo是Bar的子类型(子类或子接口),并且G是某个通用类型声明,则G不是G的子类型。


3

正确的方法是:

public void sendNotification(IMech mechanism) {

}

所以请大家阅读一些关于接口的Java教程!


3

在Java中,泛型不是那样工作的。你真正需要做的是改变方法签名为

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

或者,应该使用super而不是extends...让我查阅Effective Java的泛型章节...
编辑: Effective Java说:
这里有一个助记符可帮助您记住要使用哪种通配符类型:PECS代表producer-extends,consumer-super。 我假设这将产生IMech实例,并且extends是正确的。

1
接口的理念是你不需要知道它是哪一个。你应该能够传递一个 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);

现在我知道这些并不能直接回答你的问题,但这些是典型的用法形式,并且通常表明更具适应性的设计模式。毕竟,如果你只是确定要使用哪种机制,你真的需要发送一个类对象吗?枚举类型似乎更合适。

1

如果你这样做,会更加简洁:

public void sendNotification( IMech mechanism ){
}

你总是可以在方法内部获取类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接