So leute, ich habe nun ein schönes Workaround für mein Problem gefunden 
Natürlich ist es nicht ganz das, was ich mir erhofft habe. Aber ich spare mir damit einiges an Schreibarbeit.
Die Lösung bestand darin, das Interface des Observers als Kompositum zu implementieren. Es gibt also einzelne Observer zu jeder Klasse, und ein Kompositum, dem beliebige Observer hinzugefügt werden können. Um nun innerhalb des Kompositums zugriff auf den dynamischen Typ des observable-objects zu bekommen, muss jede Klasse die AbstractObservable erweitert eine methode [code]void accept(Observer observer)[/code] imlementieren.
Das Kompositum über die Observer leitet dann den Aufruf von [code]void update(T o)[/code] an seine Komponenten weiter. Dabei kann es durchaus passieren, dass eine ClassCastException geworfen wird (zB überwacht ein Kompositum mit einem ObserverA und einem ObserverB nur ein ObservableA. Dann kann ObservableA natürlich nicht zu ObservableB gecastet werden)
Das alles funktioniert sehr gut. Leider etwas unschön wg. der Exception.
Hier nun mal das Codebeispiel:
[CODE]public interface Observable {
void addObserver(Observer observer);
void notifyObservers();
Collection<Observer> getObservers();
void accept(Observer observer);
}
public abstract class ObservableAbstract implements Observable {
private Set<Observer> observers;
public ObservableAbstract() {
observers = new HashSet<Observer>();
}
@Override
public void addObserver(Observer observer) {
if(observer == null) {
throw new NullPointerException();
}
observers.add(observer);
}
@Override
public void notifyObservers() {
for(Observer observer : getObservers()) {
observer.update(this);
}
}
@Override
public Collection<Observer> getObservers() {
return Collections.unmodifiableCollection(observers);
}
}
public class ObservableA extends ObservableAbstract {
@Override
public void accept(Observer observer) {
observer.update(this);
}
@Override
public String toString() {
return "ObservableA";
}
}
public class ObservableB extends ObservableAbstract {
@Override
public void accept(Observer observer) {
observer.update(this);
}
@Override
public String toString() {
return "ObservableB";
}
}
public interface Observer<T extends Observable> {
/**
*
* @param o
*/
void update(T o);
}
public class ObserverA implements Observer<ObservableA> {
/**
*
* @param o
*/
@Override
public void update(ObservableA o) {
System.out.println("A");
}
@Override
public String toString() {
return "ObserverA";
}
}
public class ObserverB implements Observer<ObservableB> {
/**
*
* @param o
*/
@Override
public void update(ObservableB o) {
System.out.println("B");
}
@Override
public String toString() {
return "ObserverB";
}
}
public class ObserverGroup implements Observer<Observable> {
private Set<Observer> observers;
public ObserverGroup() {
observers = new HashSet<Observer>();
}
/**
*
* @param observer
*/
public void addObserver(Observer observer) {
observers.add(observer);
}
/**
*
* @param o
*/
@Override
public void update(Observable o) {
for(Observer observer : observers) {
try{
o.accept(observer);
} catch(ClassCastException ex) {
/*
* this might happen if an observable invoked
* the notifyObservers-method and an observer
* of another type should be updated
*/
}
}
}
}[/CODE]
Und hier nun mal ein Beispiel beim Ausführen:
[CODE]public class GenerischesInterface {
Observable observableA, observableB, observableC;
Observer observerA, observerB, observerAB;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
GenerischesInterface generischesInterface = new GenerischesInterface();
}
public GenerischesInterface() {
observableA = new ObservableA();
observableB = new ObservableB();
observableC = new ObservableC();
observerA = new ObserverA();
observerB = new ObserverB();
ObserverGroup observerGroup = new ObserverGroup();
observerGroup.addObserver(observerA);
observerGroup.addObserver(observerB);
observerAB = observerGroup;
observableA.addObserver(observerA); // A
observableA.addObserver(observerAB); // A
observableB.addObserver(observerB); // B
observableB.addObserver(observerAB); // B
observableC.addObserver(observerAB); //
observableA.notifyObservers();
observableB.notifyObservers();
observableC.notifyObservers();
}
}[/CODE]
Und der Output ist: [code]AABB[/code]