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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2859589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:47:24  来源:igfitidea点击:

Passing Interface Class as a Parameter in Java

javainterface

提问by aleclerc

I have an interface:

我有一个界面:

public interface IMech {

}

and a class that implements it

和一个实现它的类

public class Email implements IMech {

}

and a third class that has this method implemented:

以及实现此方法的第三个类:

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

now I'm trying to call that method like so

现在我正在尝试像这样调用该方法

foo.sendNotification(Email.class);

but i keep getting an exception saying:

但我不断收到一个例外说:

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

Shouldn't this work if it interfaces that class?

如果它接口那个类,这不应该工作吗?

采纳答案by axtavt

Perhaps you need

也许你需要

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

回答by Powerlord

Generics don't work that way in Java. What you really need to do it change the method signature to

泛型在 Java 中不是这样工作的。您真正需要做的是将方法签名更改为

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

Or is that superinstead of extends... let me consult Effective Java's Generics chapter...

或者是super不是extends……让我参考 Effective Java 的泛型章节……

Edit: Effective Java says:

编辑:Effective Java 说:

Here is a mnemonic to help you remember which wildcard type to use: PECS stands for producer-extends, consumer-super.

这是一个助记符,可帮助您记住要使用的通配符类型: PECS 代表生产者扩展、消费者超级。

I'm assuming this will be producing IMech instances, and that extendsis correct.

我假设这将产生 IMech 实例,这extends是正确的。

回答by Mike Daniels

Because the two classes Class<IMechanism>and Class<EmailNotification>themselves are notrelated by inheritence, even though IMechanismand EmailNotificationare.

因为这两个类Class<IMechanism>Class<EmailNotification>它们本身没有继承关系,即使IMechanismEmailNotification.

You need to make your method accept a Class<? extends IMechanism>.

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

回答by corsiKa

The idea behind interfaces is that you don't need to know which one it is. You should simply be able to pass in an IMech and call its functionality regardless of implementation. Consider the following:

接口背后的想法是您不需要知道它是哪一个。无论实现如何,您都应该能够简单地传入 IMech 并调用其功能。考虑以下:

public interface IMech {
    void sendMessage();
}

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

That's the typical usage pattern for an interface. If you're only using it for an option, perhaps you should consider using an enum instead.

这是接口的典型使用模式。如果您只是将它用作一个选项,也许您应该考虑使用枚举。

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

Now I know these don't directly answer your questions, but these are the typical forms of usage, and are usually indicative of more adaptable design patterns. After all, do you really need to send in a class object? An enum seems more appropriate if you're merely determining which mechanism to use.

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

回答by rwhit

Your parameter mechanism needs to use a bounded wildcard, like so:

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

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

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

Quoting the generics tutorial link text

引用泛型教程链接文本

In general, if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G is a subtype of G.

一般来说,如果 Foo 是 Bar 的子类型(子类或子接口),而 G 是某种泛型类型声明,则 G 不是 G 的子类型。

回答by chandler newman

the correct way is:

正确的方法是:

public void sendNotification(IMech mechanism) {

}

so please read some java tutorials about interfaces everyone!

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

回答by fastcodejava

IMO it would be cleaner if you do this :

IMO 如果你这样做会更干净:

public void sendNotification( IMech mechanism ){
}

You can always get the class inside the method.

您始终可以在方法中获取类。