tags:

views:

65

answers:

3

I am using the GWT library. There is a base class called Widget that all Widgets inherit from. Some Widgets implement certain interfaces (for example HasText), others do not. Sometimes I wish to guarantee that something being passed as an argument to a function is of a certain class AND implements a certain interface.

For example, I wish to have a function that takes a argument X, where X is of the class type Widget AND of the interface type HasText. I wish to have this behavior because only Widgets can be added to Layout containers, and HasText specifies the complete set of behaviors that I actually need from said Widget.


In pseudocode form, it might be:

public void fx(I_AM_A_Widget_AND_IMPLEMENT_INTERFACE_HasText x){
    //do stuff with x, which is guaranteed to be a Widget AND implement HasText
}

Is this in any way possible in Java? If there are multiple ways to do so, is there a preferred/better way?

+7  A: 

You might be able to use a generic method here:

public <T extends Widget & HasText> void fx(T x)

The compiler will infer the type of T automatically, so no extra syntax when calling the method.

Anon.
+1  A: 

The way I would handle this is to add a method to the HasText interface to return the Widget, and the implementation would just return this.

    public class MyClass extends Widget implements HasText {

            @Override
            public Widget getMyWidget() {
                return this;
            }
    }

So if a method needs a Widget, you just call the HasText's getMyWidget() method. It does create some boilerplate, but it helps with the static type checking.

If you don't care that much for the static type checking, you could simply have a contract (statement in the JavaDoc) that the HasText interface is only intended to be implemented on Widgets, and then just cast whenever you need the Widget.

Then you method just looks like

 public void fx(HasText text) //...
Yishai
A: 

Thank you for both of your solutions. In the end, I decided that the best solution was to simply specify bounded types at the top of the class definition. For example, I used the form

public class Example<Editable extends Widget & HasText> {
  private Editable editor = null;

  //do stuff in various methods (including the constructor) with the 
  //editor variable and the Editable type.
}

I picked this solution for a few reasons.

  1. The two above mentioned solutions both require the use of methods (boilerplate) that do not really relate to business functionality, but are instead related to circumventing the limitations of the language.
  2. Anon, your solution is correct, but I have the problem of being unable to declare a variable that would hold a reference to the generic object your method returns. I believe this to be the case because the generic object returned from your method only exist at the level of the method, and not the class. Perhaps I have missed some syntax that would allow me to declare variables that have generic properties?
  3. Yishai, your solution works as well, but then I have the problem of having to declare a separate method in every interface that I wish to guarantee support for, this seemed cumbersome.
  4. These bounded types declared in the class "header" only need be declared once. It seems like the most terse declaration of generic bounded types available in Java.
  5. You can declare more than one bounded type in the class "header".
  6. If you use this method exclusively, all the potential bounded types are declared at the same location in your code.

The declaration of bounded types in the class header is the best solution I have run across. I would still be interested in knowing if their is a way to permanently declare (so that it might be accessed across different classes) a bounded type, rather than declaring them per class.

Stephen Cagle