Java: Подклас на типа в сигнатура на метод

Добре. Така че се опитвам да настроя GUI за приложение, използвайки модела на наблюдателя. По стандартен начин; ако Observable се актуализира, той извиква метода за актуализиране на всички свои наблюдатели, предавайки ComponentUpdateEvent, както следва:

public interface Observable {
 ArrayList<Observer> observers = new ArrayList<Observer>();

 public void updateObservers();

 public void addObserver(Observer observer);

 public void removeObserver(Observer observer);
}

public interface Observer {
 public void update(ComponentUpdateEvent updateEvent);
}

public abstract class ComponentUpdateEvent {
 public abstract ComponentType getComponentType();
}

Имам редица различни компоненти, които имплементират Observable, в "моделната" страна на приложението. Всеки тип компонент има отделен подклас на класа Drawer, който имплементира Observer, за изобразяване в JPanel.

Проблемът е, че се опитвам да направя така, че когато се извика методът за актуализиране на подклас на Drawer, предаваният параметър updateEvent да може да бъде подклас на ComponentUpdateEvent.

Въпреки това, очевидно, ако се опитам да направя това, както следва:

 @Override
 public void update(ConsoleUpdateEvent updateEvent) throws Exception {
  if (this.componentType != updateEvent.get)) {
   throw new Exception("ComponentType Mismatch.");
  }
  else {
   messages = updateEvent.getComponentState(); 
  }
 }

Получавам грешката на компилатора:

The method update(ConsoleUpdateEvent) of type ConsoleDrawer must override or implement a supertype method.

Тъй като подписът на метода не е същият. Изглежда не мога да преодолея този проблем, без да имам отделни класове наблюдатели за всеки тип компонент, възможно ли е да се реши този проблем с генерични продукти? Всяка помощ ще бъде оценена.


person carnun    schedule 09.12.2010    source източник


Отговори (3)


Вашият интерфейс трябва да декларира, че е throws Exception, за да разреши грешката на компилатора ви. Причината за това е, че не предавате тип клас, а интерфейса на наблюдателя. Така че, ако един клас, който имплементира Observable, хвърли изключение, извикващият клас няма да знае за това, освен ако интерфейсът не го посочи.

person Michael K    schedule 09.12.2010

Във вашия Observer интерфейс вашият update() метод не throw Exception, а вашият ConsoleDrawer.update() го прави. 2-те не са еднакви според java.

Или премахвате throw Exception на ConsoleDrawer, или добавяте изключението в интерфейса Observer.

person Buhake Sindi    schedule 09.12.2010

По принцип Java ви позволява да отслабите върнатата стойност, когато замените метод или да подсилите параметрите. В този случай обаче се опитвате да отслабите параметъра.

Може би генериците могат да помогнат. Трябва да призная, че не съм пробвал кода по-долу, това е само по памет:

Можете да опитате да използвате генерични в сигнатурата на интерфейса Observer:

public interface Observer<T>

or

public interface Observer<T extends ComponentUpdateEvent>

В допълнение към това бих преработил подписа на интерфейса Observable.

public void addObserver(Observer<T extends ComponentUpdateEvent> observer)
person Yoni    schedule 09.12.2010
comment
Или вашите определения за укрепване и отслабване са обърнати от моите, или сте получили това първо изречение наобратно. Типът връщане на отменен метод може да бъде по-специфичен (това, което бих нарекъл по-силен), докато параметрите могат да бъдат по-малко специфични (по-слаби). Типовете, които хвърля, се държат подобно на връщаните типове. - person Laurence Gonsalves; 09.12.2010