Riley Lark
Riley Lark

Reputation: 20890

Way to specify multiple interfaces in Java

I have two interfaces, HasClickHandlers and DoesFancyFeedback. Then I have some UI objects that implement both interfaces - for example, a Button that implements both has click handlers and also does fancy feedback.

In my code that's declaring Buttons, I don't want to actually say Button because maybe later I'll want it to be, I don't know. An Image that has click handlers and does fancy feedback. So instead of being specific and saying something like:

Button saveButton = aButtonIPassedIn;
saveButton.addClickHandler();
saveButton.doFancyFeedback();

I want to say,

{HasClickHandlers + DoesFancyFeedback} clickyFeedbackThing = aThingIPassedIn;
clickyFeedbackThing.addClickHandler();
clickyFeedbackThing.doFancyFeedback();

I want the compiler to require that aThingIPassedIn implement both HasClickHandlers and DoesFancyFeedback.

I could create an interface that extends those two interfaces, and use that. Is there any easier/less verbose way?

Upvotes: 13

Views: 5180

Answers (6)

Niklas
Niklas

Reputation: 9

No need for a third interface nor additional method.

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

Upvotes: 1

Alexander Pogrebnyak
Alexander Pogrebnyak

Reputation: 45576

You may try to use generics:

public < T extends HashClickHandlers & DoesFancyFeedback > void foo (
        T aThingIPassedIn
    )
{
    aThingIPassedIn.addClickHandler( );
    aThingIPassedIn.doFancyFeedback( );
}

Upvotes: 5

OscarRyz
OscarRyz

Reputation: 199234

No, there is no such a thing in Java.

You would have to use the option you mention of creating a third interface. That way you'll be explicitly declaring your intention to use a new type.

Is not that verbose after all ( considering the alternative ), because you would just type:

public interface FancyWithHandler 
       extends HashClickHandlers , DoesFancyFeedback {} 

You don't need to include the methods. And then just use it:

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

While the generic option looks interesting, probably at the end you'll end up creating a much more verbose thing.

Upvotes: 1

duffymo
duffymo

Reputation: 308763

I wouldn't want a Button to implement any of those interfaces. What you're describing sounds more like the province of an event listener. Better to have the listener implement plain and fancy click handlers, and pass the listener into the Button or UI component. It's more of a delegation model that keeps processing out of the UI components and in separate classes that you can change at will.

Upvotes: -1

thejh
thejh

Reputation: 45568

Although that would be ugly, you could propably make it an Object and cast it. For the calling method, it would be the easiest way.

Upvotes: 0

AlexR
AlexR

Reputation: 115338

I do not think that there is a better way to do what you want. I just wanted to suggest you to do the following. You can create method (let's call it foo) that accepts argument that requires 2 interfaces:

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

Please pay attention on one ampersand between 2 your interfaces.

Upvotes: 28

Related Questions