Dlaczego niektóre interfejsy mają zdefiniowane metody?

0

Cześć.

Może pytanie nieco naiwne, ale serio dało mi mocną zagwozdkę i temat do myślenia. Czy mógłby mi ktoś wyjaśnić, dlaczego niektóre interfejsy, jak np. Iterator albo Enumeration, mają zdefiniowane metody? Próbowałem znaleźć odpowiedź w Internecie, ale jedyne co znalazłem, to metody default, ale chyba nie o to tu chodzi, bo one są dopiero od Javy 1.8...

Czy mógłby ktoś mi to przystępnie wytłumaczyć? Będę naprawdę wdzięczny, żyłem w przekonaniu, że interfejs może mieć tylko deklaracje metod i teraz mój programistyczny światek mocno mi się chwieje ;)

0

A możesz pokazać przykład? Enumeration nie ma żadnych zaimplementowanych metod a Iterator ma jedną i jest to metoda default (chyba ze w Javie 9 coś doszło, nie mam JDK 9 pod ręką).

0

@zlatan55 chodzi chyba o to, że stare interfejsy mają defaultowe metody. Tak, w Javie 8 pododawano metody default do wielu starych interfejsów.

0

Pics or it didn't happen

0

@Shalom: Na przykład w klasie serwleta, w metodach doGet, doPost, metoda request.getParameterNames(); zwraca obiekt interfejsu Enumeration< String>, który mogę sobie przechodzić metodami hasMoreElements() i nextElement(). Iterator podobnie, posiada hasNext(), remove()...

Czy to wynika z tego, co napisał @jarekr000000, że stare interfejsy mają jakieś defaultowe metody? Czy ja tu czegoś nie do końca rozumiem?

0

Stare interfejsy nie mają implementacji. To co dostajesz to nie czysty Iterator, tylko obiekt klasy która implenetuje ten interfejs i to ona implementuje metody które są wymagane. Na tym polega cała idea interfejsów - nie wiesz jak to działa pod spodem bo nie musisz. Wystarczy że wiesz jak użyć hasMoreElements() i nextElements().

0

@zlatan55: o_O a odróżniasz ty interfejs od jego implementacji? Jak napisze sobie:

class A implements Enumeration<String>{
boolean hasMoreElements(){ return true;}
String nextElement(){return "ya dun goofed";}
}

To nic nie stoi na przeszkodzie zeby zrobić:

Enumeration<String> x = new A();
System.out.println(x.hasMoreElements());
System.out.println(x.nextElement());
0
krzysiek050 napisał(a):

Stare interfejsy nie mają implementacji. To co dostajesz to nie czysty Iterator, tylko obiekt klasy która implenetuje ten interfejs i to ona implementuje metody które są wymagane. Na tym polega cała idea interfejsów - nie wiesz jak to działa pod spodem bo nie musisz. Wystarczy że wiesz jak użyć hasMoreElements() i nextElements().

No właśnie to jakoś do mnie nie dociera - co to jest za klasa, która implementuje ten Enumerator? W dokumentacji jest napisane, że tylko jedna klasa nieutworzona przeze mnie implementuje Enumeration (StringTokenizer), ale przecież ona tu nie występuje?
Czy ta klasa której obiekt dostaję jest właśnie po to "żebym sobie nie zawracał głosy interfejsem" i nie ma sensu drążyć, co to właściwie za klasa?

Tak @Shalom, ja to rozumiem, tylko właśnie ty napisałeś wprost klasę implementującą interfejs i te metody, a w tym moim przykładzie takiej klasy "jak na tacy" nie ma. Może komuś doświadczonemu to się wydaje głupi problem, ale według mnie początkującego to wcale nie jest takie oczywiste ;)

0

@zlatan55 jak to "nie ma"? Przeciez skądś sie tam ten Enumerator bierze w kodzie. Nawet jeśli nie ma tam bezpośrednio jakiegoś "new" w kodzie na który patrzysz, to jak pokopiesz głębiej to się znajdzie. Jeśli ten Enumerator jest brany z jakiejś metody jako jej wynik, to skocz do niej debugerem i zobacz skąd ona ten obiekt bierze. Gdzieś na końcu znajdziesz to new.

0

Ok, to jeszcze jedno tak w celu upewnienia się. Wywołałem sobie:

Enumeration<String> en = request.getParameterNames();
System.out.println( en.getClass() );

I print wyświetlił: "class java.util.Collections$3". Czyli 'en' jest tak naprawdę obiektem klasy Collections$3, która implementuje Enumeration? Tylko ciekawe co to za klasa, jeżeli nie da się tak wprost zadeklarować jej obiektu:

Collections$3 temp;

Ciekawe to wszystko i wydaje mi się, że już lepiej rozumiem, ale nadal ta klasa Collections$3 jest dla mnie nieco tajemnicza ;)

0

Serio nie potrafisz zrobic ctrl+klik albo skoczyć do implementacji? o_O Przecież tu nie ma co zgadywać. Otwierasz implementacje i widzisz że np. tomcatowa implementacja robi:

return Collections.enumeration(this.parameters.keySet());

A Collections.enumeration to nic innego jak po prostu:

    public static <T> Enumeration<T> enumeration(final Collection<T> c) {
        return new Enumeration<T>() {
            private final Iterator<T> i = c.iterator();

            public boolean hasMoreElements() {
                return i.hasNext();
            }

            public T nextElement() {
                return i.next();
            }
        };
    }

Czyli tworzy anonimową klasę implementującą enumerator.

1 użytkowników online, w tym zalogowanych: 0, gości: 1