I'm trying to implement Observable pattern with an abstract class (so that my subclasses don't provide a common implementation). I want polymorphic functions for different Observer types.
I have an interface IObservable:
public interface IObservable { /* also used version IObservable<O> */ <O> void registerObserver(O o); <O> void removeObserver(O o); } I wrote abstract class ObservableBase:
public abstract class ObservableBase implements IObservable { protected abstract <O> Set<O> getCollection(O o); @Override public <O> void registerObserver(O o) { getCollection(o).add(o); } @Override public <O> void removeObserver(O o) { getCollection(o).remove(o); } } And I want my concrete class to implement IObservable for different types of Observers:
// This is what it'd look like if I just implemented it by hand for generic interface public ConcreteClass implements IObservable<Observer1>, IObservable<Observer2> { @Override public void registerObserver(Observer1 o) {} @Override public void registerObserver(Observer2 o) {} @Override public void removeObserver(Observer1 o) {} @Override public void removeObserver(Observer2 o) {} } My idea is to put register/remove functionality in the base abstract class and provide only collection for this operations. But I cant wrap my hand around this. If I declare in the ConcreteClass specific type for getCollection, compiler complains "Method does not override method from its superclass".
Something like:
public ConcreteClass extends ObservableBase { protected Set<Observer1> getCollection(Observer1 o) {/*...*/} protected Set<Observer2> getCollection(Observer2 o) {/*...*/} } Is it possible?
getCollectioninConcreteClasstwice? You can have multipleConcreteClassimplementations that overridegetCollectionfor different observers. Does that suit you?IObservable, the type parameters are method scoped. So, since there are no constraints on those parameters, each method may as well accept Object no matter what the type parameter onIObservableis. This breaks the inheritance model you seem to be aiming for.getCollection(Observer1 o);getCollection(Observer2 o);. Or maybe to have one method ``getCollection(Class<T> o)`and then inside the function return proper set for provided type.