tags:

views:

95

answers:

5

I'm looking to create a set of functions which all implementations of a certain Interface can be extended to use. My question is whether there's a way to do this without using a proxy or manually extending each implementation of the interface?

My initial idea was to see if it was possible to use generics; using a parameterized type as the super type of my implementation...

public class NewFunctionality<T extends OldFunctionality> extends T {
    //...
}

...but this is illegal. I don't exactly know why this is illegal, but it does sort of feel right that it is (probably because T could itself be an interface rather than an implementation).

Are there any other ways to achieve what I'm trying to do?

EDIT One example of something I might want to do is to extend java.util.List... Using my dodgy, illegal syntax:

public class FilterByType<T extends List> extends T {

 public void retainAll(Class<?> c) {
  //..
 }

 public void removeAll(Class<?> c) {
  //..
 } 

}
+1  A: 

What prevents you from just adding new methods to the interface?

If you can't just add the new functionality to old interface, you could consider making another interface and then an implementation which merely implements those two. Just to be clear, in code this is what I mean:

// Old functionality:
public interface Traveling {
    void walk();
}
// Old implementation:
public class Person implements Traveling {
    void walk() { System.out.println("I'm walking!"); }
}
// New functionality:
public interface FastTraveling {
    void run();
    void fly();
}
// New implementation, option #1:
public class SuperHero extends Person implements FastTraveling {
    void run() { System.out.println("Zoooom!"); }
    void fly() { System.out.println("To the skies!"); }
}
// New implementation, option #2:
public class SuperHero implements Traveling, FastTraveling {
    void walk() { System.out.println("I'm walking!"); }
    void run() { System.out.println("Zoooom!"); }
    void fly() { System.out.println("To the skies!"); }
}
Esko
Thanks for the answer, Esko. I've added an example which, hopefully, illustrates what I'm getting at more effectively than my initial question... :)
Chris R
+3  A: 

You can achieve something like this using a programming pattern known as a 'decorator' (although if the interface is large then unfortunately this is a bit verbose to implement in Java because you need to write single-line implementations of every method in the interface):

public class FilterByType<T> implements List<T> {

    private List<T> _list;

    public FilterByType(List<T> list) {
        this._list = list;
    }

    public void retainAll(Class<?> c) {
        //..
    }

    public void removeAll(Class<?> c) {
        //..
    }

    // Implement List<T> interface:

    public boolean add(T element) {
        return _list.add(element);
    }

    public void add(int index, T element) {
        _list.add(index, element);
    }

    // etc...

}

Alternatively, if the methods don't need to access protected members, then static helper methods are a less clucky alternative:

public class FilterUtils {

    public static void retainAll(List<T> list, Class<?> c) {
        //..
    }

    public static void removeAll(List<T> list, Class<?> c) {
        //..
    }

}
Todd Owen
Cheers for the answer - the decorator pattern was one of the techniques I was thinking of when I mentioned proxying the exitsting implementation. Hadn't thought of using a helper class though - maybe that's the way to go...
Chris R
+1  A: 

I think it's illegal because you can not guarantee what class T will be. Also there are technical obstacles (parent's class name must be written in bytecode, but Generics information get lost in bytecode).

You can use Decorator pattern like this:

class ListDecorator implements List {
  private List decoratingList;
  public ListDecorator(List decoratingList){
    this.decoratingList = decoratingList;
  }

  public add(){
     decoratingList.add();
  }

  ...
}

class FilterByArrayList extends ListDecorator {
  public FilterByAbstractList () {
    super(new ArrayList());
  }
}
Nikita Prokopov
A: 

I'm afraid it's not clear what do you want to get.

Basically, I don't see any benefit in using 'public class NewFunctionality<T extends OldFunctionality> extends T' in comparison with 'public class NewFunctionality extends OldFunctionality' ('public class FilterByType<T extends List> extends T' vs 'public class FilterByType<T> implements List<T>')

denis.zhdanov
If my filter simply implements the List interface, I'd have to implement every method defined by this interface - effectively I'd be proxying the existing functionality. I'm not necessarily saying this isn't the correct approach, but I was interested to know if anyone had any other ideas.
Chris R
Ok, so, why don't your extends target List implementation? E.g. class FilterByType<T> extends ArrayList<T>
denis.zhdanov
Of course I can do that - but then I'd need to do the same for every implementation (ArrayList, Vector, LinkedList etc). I should add that this example is not necessarily how I want to use this functionality - it's just an example.
Chris R
As far as I understand, you want to decorate the functionality, not to extend it. I.e. if we are talking about List you want to be able to get any List implementation and change its behavior/add new behavior. Is that right?
denis.zhdanov
+1  A: 

There is a delegation/mixin framework that allows a form of this. You can define a new interface, implement a default implementation of that interface, then request classes which implement that interface but subclass from elsewhere in your hierarchy.

It's called mixins for Java, and there's a webcast right there that demonstrates it.

Suppressingfire
Thanks! I'll give that a look.
Chris R