Czy muszę nadpisać wszystkie metody?

Czy muszę nadpisać wszystkie metody?
NI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 54
0

Dobry wieczór. Właśnie piszę klasę implementującą kolejkę cykliczną. Klasa ta implementuje interfejs BlockingQueue<E>, a przez to jeszcze kilka innych. Problem w tym, że nadpisałem kilka potrzebnych mi metod, jednak kompilator wyrzuca, że mam nadpisywać jeszcze kolejne. Wychodzi na to, że potrzebne czy nie (nie potrzebuję np. remove(Object o) z BlockingQueue<E>, bo wystarczy mi remove() z Queue<E>), ale musiałbym nadpisać metody ze wszystkich interfejsów. A to, delikatnie mówiąc, jest bez sensu. Czy istnieje jakiś sposób, by to obejść?

M4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0

Nie, co najwyzej mozesz te metody zostawic puste

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
2

Jeśli implementujesz jakiś interfejs to MUSISZ implementować wszystkie jego metody. Inaczej nie miałoby to sensu! Przecież ktoś teraz może wziąć tą twoja klasę TwojaKlasa i zrobić:

Kopiuj
BlockingQueue<String> queue = new TwojaKlasa<>();
queue.remove(cośtam);

I co teraz? Możesz zostawić puste implementacje, albo lepiej rzucać jakies NotImplementedError czy coś, ale to też bardzo biedne rozwiązanie.

Niemniej normalnie to się robi jednak jakąś delegacje -> masz swoją klasę która ma w sobie obiekt jakiejś standardowej kolejki. Nadpisujesz metody które cię interesuję, a resztę metod delegujesz do tej kolejki którą masz pod spodem:

Kopiuj
class MojaKolejka<T> implements Queue<T>{
    private final queue = new LinkedList<>();

    @Override
    public boolean add(T element){
        // jakaś nasza specjalna logika
        return  queue.add(element);
    }

    @Override
    public boolean offer(T element){
        return queue.offer(element); // goła delegacja
    }
}
NI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 54
0

Rozumiem. Zostawienie tych metod nie wydaje mi się bezpiecznym rozwiązaniem, ale chyba tak zrobię (lub wewnątrz nich wywołam ich przeciążone odpowiedniki). Pytanie zadałem, bo wspomniane przez @Shalom zastosowanie metody remove(Object) wydaje mi się absolutnie bez sensu. W kolejce cyklicznej mogę usunąć tylko element będący głową, a nie wybrany przeze mnie.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
3

To nie ma znaczenia, bo implementujesz jakiś OGÓLNY interfejs! Czyli mówisz ze twoja klasa dostarcza taką funkcjonalność. Zasada L z SOLID się kłania. Jeśli chcesz mieć KolejkęCykliczną to zrób interfejs CyclicQueue<T> który ma tylko te metody które mają sens dla tej kolejki. Tutaj znowu kłania się Interface Segregation Principle. Po co chcesz implementować BlockingQueue<E> skoro twoja klasa w ogóle do tego interfejsu nie pasuje? o_O

NI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 54
0

Problem w tym, że muszę dziedziczyć po BlockingQueue<E>, więc stworzenie dodatkowego interfejsu nie zmieni mojej sytuacji, bo i tak muszę przesłonić wszystko. Prawdopodobnie zostanę przy wypisaniu wszystkich metod, wywoływaniu metod mających sens wewnątrz metod "bezsensownych" i oznaczeniu tych drugich jako "depracated".

S9
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Warszawa
  • Postów: 3573
0

@niepamietamloginu: na pewno musisz implementowac BlockingQueue? Czemu tak?

NI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 54
0

Niestety. Zostało to narzucone w treści zadania.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
0

Ale właściwie czemu uważasz że np. usuwanie losowego elementu "nie ma sensu"? Bo nie da sie tego wykonać w O(1)? LinkedList też na to pozwala, mimo że też w praktyce tylko head i tail można usunać w O(1), a losowe usuwanie to O(n).
Jeśli masz w treści zadania ze to ma być BlockingQueue to musisz zaimplementować wszystkie metody.

tampir
  • Rejestracja: dni
  • Ostatnio: dni
0

Możesz też spróbować dziedziczyć z klasy AbstractQueue<T> i wtedy nie musisz nadpisywać metody remove(Object) i paru innych.

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
1

Słowo klucz – delegacja. Zamiast samodzielnie implementować wszystkie metody, wydeleguj je do istniejącej implementacji:

Kopiuj

class MyCyclicQueue<T> implements BlockinigQueue<T>, CyclicQueue<T> {
    
   private final BlockinigQueue<T> delegate;

   public CyclicQueue(BlockinigQueue<T> delegate){
       this.delegate = delegate;
   } 

   public boolean add(T t){
       return delegate.add(t);
   }
} 

Do tego zdefiniuj interfejs CyclicQueue, który będzie zawierał tylko metody, które masz zamiar zaimplementować samodzielnie – z uwzględnieniem odpowiednich nazw. Nadal nie będzie to 100% SOLID, ale już będzie lepiej.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.