tags:

views:

61

answers:

3

In Java generics you can use "&" to specify multiple interfaces as type bounds for a type parameter. This allows us for example to manipulate objects of different types with common interfaces to be manipulated uniformly even if there is not an parent interface for those common ones. My question is, how can this be used? For What purposes? I can imagine using this feature for collections, but how is it really than creating a new interface? This cannot be used dynamically, nor for type parameters. Is it just a syntactic sugar, or is there real use case for this feature?

+3  A: 

There are use cases for this, but there are generally alternate ways to achieve the same results. This is just another tool in the toolbox available for Java developers.

But let's say you have a JPanel that takes a custom JComponent that implements MyInterface. It can be one of several components, depending on another option selected on the panel. You want to reference this as a JComponent so that you can interact with it and place it, yet you also need to reference it as MyInterface to call some custom methods.

In this case, you cannot simply add the JComponent methods you need to MyInterface, because you have to call JPanel.add(component to put it on the overall panel. You can't make your interface somehow extend JComponent because Java doesn't work like that. You cannot create a custom extentsion to JComponent, because perhaps sometimes your object is another panel, sometimes it's a text field, and you don't want to restrict yourself. So you would reference it as a JComponent & MyInterface.

Erick Robertson
As you said in first paragraph, this can be achieved by other means, e.g. having all my custom components inherit from an abstract class extending JComponent and implementing MyInterface.
Gabriel Ščerbák
The problem is if you want some of your custom components to extend JPanel, and some to extend JTextField, etc. You can't simply create an abstract class extending JComponent.
Erick Robertson
I had an app one time that handled objects composed of many different types of GUI components (all eventually inheriting from JComponent) but all had a common interface for interacting back with their parent object. In this case I could think of no other way to handle this problem - just like Erick said.
BigMac66
+3  A: 

Here is an example taken from my Java Generics book:

public static <S extends Readable & Closeable, 
              T extends Appendable & Closeable> 
       void copy(S source , T target, int size){

    //code to copy from source to target 

}

The method above takes any source that implements both Readable and Closeable and any target that implements both Appendable and Closeable and copies from source to target. You might wonder why we can't simplify it to:

public static void copy(Reader source, Writer target, int size)

This will indeed admit most of the same classes but not all of them. For instance, PrintStream implements both Appendable and Closeable, but is not a subclass of Writer. Furthermore, you can't rule out the possibility that some programmer using your code might have his or her own custom class that, say, implements Readable and Closeable but is not a subclass of Reader.

dogbane
Rather than trying to use a class implementing both interfaces I would try defining my own interface extending both required. However I see, that this spares me of writing adapters for classes implementing both interfaces, not my own.
Gabriel Ščerbák
A: 

I was thinking, that an interresting use case might be using it in combination with multiple inheritance (composition and delegation), especially with generalization sets to create stronger constraints. For example in use case modeling, an actor might be an organization, system or subsystem, but at the same time also primary, secondary and ternary actor. All of these might require different behaviour (e.g. ternary actor has interrests, but primary has goals), so they cannot be collapsed. Now to work with a bank, which might be Ternary actor as well as organization, you would use this feature.

Gabriel Ščerbák
You don't offer a lot of details here, so I don't see anything that couldn't be handled by having Actor be a superclass or interface for Organization, System, and SubSystem. Even if primary, secondary, and tertiary actors all had different behavior, there's never a guarantee that the current abstraction will hold up in the future. All of that could be abstracted into the Actor inteface and you wouldn't have a need for this pattern at all.
Erick Robertson