4

ジェネリックのObserverインターフェースとObservableクラスを作成しましたが、ジェネリックの問題のためにクラスをコンパイルできません。なぜ私がやろうとしていることが禁じられているのか正確にはわかりません。コードは次のとおりです。

public class Observable<U> {

    private List<Observer<Observable<U>, U>> _observers = 
            new ArrayList<Observer<Observable<U>, U>>();

    public void addObserver(Observer<? extends Observable<U>, U> obs) {
        if (obs == null) {
            throw new IllegalArgumentException();
        }
        if (_observers.contains(obs)) {
           return;
        }
        _observers.add(obs); // This line does not compile
    }

    public void notifyObservers(U data) {
        for (Observer<? extends Observable<U>, U> obs : _observers) {
            // After correction of the list declaration, this line will not compile
            obs.update(this, data); 
        }        
    }
}

interface Observer<T, U> {
    public void update(T entity, U arg);
}
4

2 に答える 2

6

_observers定義を次のように変更します。

private List<Observer<? extends Observable<U>, U>> _observers = 
        new ArrayList<Observer<? extends Observable<U>, U>>();

サブクラスを許可する場合は、使用している場所だけでなく、宣言でこれを指定する必要があります

于 2009-07-09T13:41:56.697 に答える
3

これを試して:

 public class Observable<U> {

        private List<Observer<Observable<U>, U>> _observers =
                new ArrayList<Observer<Observable<U>, U>>();

        public void addObserver(Observer<Observable<U>, U> obs) {
            if (obs == null) {
                throw new IllegalArgumentException();
            }
            if (_observers.contains(obs)) {
               return;
            }
            _observers.add(obs);            }

        public void notifyObservers(U data) {
            for (Observer<? super Observable<U>, U> obs : _observers) {
                obs.atualizar(this, data);
            }
        }
    }

    interface Observer<T, U> {
        public void atualizar(T entity, U arg);
    }

ここで根本的な問題を説明すると、ジェネリックは明示的なダウンキャストを強制しています。したがって、U の実装に対して「Observable」を取得してコレクションに入れることはできません。そのコレクションは、何もではなく特定のタイプの U を取得するように定義されているためです。

このタイプのユース ケースでは、ジェネリックには制限があり、そのようなタイプ セーフな方法では目的を達成できない場合があります。

編集:これはあなたのために働くでしょうか?

public class Observable<U> {

       private List<Observer<U>> _observers =
               new ArrayList<Observer<U>>();

       public void addObserver(Observer<U> obs) {
           if (obs == null) {
               throw new IllegalArgumentException();
           }
           if (_observers.contains(obs)) {
              return;
           }
           _observers.add(obs);            }

       public void notifyObservers(U data) {
           for (Observer<U> obs : _observers) {
               obs.atualizar(this, data);
           }
       }
   }

   interface Observer<U> {
       public void atualizar(Observable<U> entity, U arg);
   }
于 2009-07-09T13:57:00.047 に答える