在Java中指定多个接口的方法

在Java中指定多个接口的方法,java,inheritance,interface,Java,Inheritance,Interface,我有两个界面,HasClickHandlers和DoesFancyFeedback。然后我有一些实现这两个界面的UI对象-例如,一个实现这两个界面的按钮,它既有单击处理程序,也有奇特的反馈 在我声明按钮s的代码中,我不想实际说按钮,因为我不知道,也许以后我会想要它。一个图像,它具有点击处理程序并提供奇特的反馈。因此,与其说得具体一些,不如说: Button saveButton = aButtonIPassedIn; saveButton.addClickHandler(); saveButto

我有两个界面,
HasClickHandlers
DoesFancyFeedback
。然后我有一些实现这两个界面的UI对象-例如,一个实现这两个界面的
按钮
,它既有单击处理程序,也有奇特的反馈

在我声明
按钮
s的代码中,我不想实际说
按钮
,因为我不知道,也许以后我会想要它。一个
图像
,它具有点击处理程序并提供奇特的反馈。因此,与其说得具体一些,不如说:

Button saveButton = aButtonIPassedIn;
saveButton.addClickHandler();
saveButton.doFancyFeedback();
我想说,

{HasClickHandlers + DoesFancyFeedback} clickyFeedbackThing = aThingIPassedIn;
clickyFeedbackThing.addClickHandler();
clickyFeedbackThing.doFancyFeedback();
我希望编译器要求在
中同时实现
HasClickHandlers
DoesFancyFeedback


我可以创建一个扩展这两个接口的接口,并使用它。有没有更简单/更简洁的方法?

不,Java中没有这样的方法

您必须使用您提到的创建第三个接口的选项。这样,您将明确声明您打算使用新类型

毕竟不是那么冗长(考虑到其他选项),因为您只需键入:

public interface FancyWithHandler 
       extends HashClickHandlers , DoesFancyFeedback {} 
您不需要包括这些方法。然后使用它:

FancyWithHandler clickyFeedbackThing = aThingIPassedIn;
clickyFeedbackThing.addClickHandler();
clickyFeedbackThing.doFancyFeedback();     

虽然通用选项看起来很有趣,但最终可能会创建一个更详细的东西。

我不认为有更好的方法来做你想做的事情。 我只是想建议你做以下事情。您可以创建方法(我们称之为foo),该方法接受需要2个接口的参数:

<T extends HasClickHandlers & DoesFancyFeedback> void foo(T arg);
void foo(T arg);

请注意两个接口之间的一个和

您可以尝试使用泛型:

public < T extends HashClickHandlers & DoesFancyFeedback > void foo (
        T aThingIPassedIn
    )
{
    aThingIPassedIn.addClickHandler( );
    aThingIPassedIn.doFancyFeedback( );
}
publicvoid foo(
阿廷吉普塞丁酒店
)
{
addClickHandler();
a.doFancyFeedback()中传递的消息;
}

尽管那会很难看,但你可以把它变成一个对象,然后将它投射出去。对于调用方法,这将是最简单的方法。

我不想用按钮来实现这些接口中的任何一个。您所描述的内容听起来更像是事件侦听器的范围。最好让监听器实现简单而奇特的点击处理程序,并将监听器传递到按钮或UI组件中。它更像是一种委托模型,它将处理过程排除在UI组件之外,并保留在单独的类中,您可以随意更改这些类。

无需第三个接口或其他方法

Optional.ofNullable((HasClickHandlers & DoesFancyFeedback)clickyFeedbackThing).ifPresent(then -> {
    then.addClickHandler();
    then.doFancyFeedback();
});

OP说:“我可以创建一个扩展这两个接口的接口,并使用它。有没有更简单/更简洁的方法?”我错过了这一部分,我改变了我的答案。理论上,你可以用泛型来实现这一点,我想——对它必须实现这两个接口的论点施加约束。然而,我已经有一段时间没有使用Java泛型了,所以我的内存可能有点被.NET泛型污染了。关于如何实现这一点的任何细节(哈)都将非常好!哇,谁知道!?在此之后,将
arg
强制转换为
hascackhandlers
DoesFancyFeedback
,总是安全的,对吗?这比为我想要的每一个接口组合创建一个复合接口要容易得多。@Riley:在这种情况下,你不必强制转换它,只需调用它上的方法。我遇到了这个问题@Riley:我猜你们在谈论一种由视图类实现的
显示
接口的方法,对吧?我没有看到的是如何让实例在演示者代码中实现
hascackhandlers
DoesFancyFeedback
。我想在
显示
界面中需要类似于
T getFancy()
的东西。对于这个方法的实现,我看不到没有强制转换的解决方案。你能告诉我你是怎么做到的吗?谢谢。@z00bs:我最终进行了强制转换,但我在构造函数中添加了一个检查,以确保指定的任何对象都是多个必需接口的实例。我将此100%保留在显示代码中-我从未将其中一个对象传回演示者。相反,我将公开方法写入到显示器中,显示器执行强制转换工作。这使复杂的继承检查保持在单个文件中。我从来没有尝试过你建议的方法——似乎它会起作用,我不明白为什么它需要铸造。然而,在没有显式检查的情况下,您不会立即得到错误。@Riley:所以您有像
void addClickHandler(ClickHandler handler)这样的方法
在演示者使用的
显示
界面中?这是一种声明参数的好方法-有没有任何方法可以像这样声明字段或其他变量?您不希望按钮实现
HasClickHandlers
?这不是处理,这是用户界面-
DoesFancyFeedback
在本例中是“在按钮文本旁边显示一个旋转加载图标”,而
HasClickHandlers
是“当用户单击此按钮时告诉我”。毕竟,如果不是按钮本身,您建议的侦听器附加到什么?HasClickHandlers在做什么?只是一个true/false来表示是否注册了某个内容?