简体   繁体   中英

Extending functionality of all implementations of an Interface?

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) {
  //..
 } 

}

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) {
        //..
    }

}

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!"); }
}

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());
  }
}

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.

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>' )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM