Streszczenie interfejsu Java

197

Rozważ przykład (który kompiluje się w Javie)

public abstract interface Interface {
    public void interfacing();
    public abstract boolean interfacing(boolean really);
}

Dlaczego konieczne jest „zadeklarowanie” interfejsu jako abstrakcyjne? Czy istnieją inne reguły dotyczące abstrakcyjnego interfejsu?


Wreszcie: jeśli abstractjest przestarzały, dlaczego jest zawarty w Javie? Czy istnieje historia abstrakcyjnego interfejsu?

Buhake Sindi
źródło
5
Nie jest duplikatem, biorąc pod uwagę część „ Wreszcie: .... ”.
aioobe,
To powiązane pytanie przytacza prawdziwy przykład: stackoverflow.com/questions/4380796/…
Raedwald
1
I dlaczego Eclipse domyślnie dodaje „streszczenie” podczas „wyodrębniania interfejsu”?
ModdyFire
@ModdyFire, proszę opracować?
Buhake Sindi

Odpowiedzi:

447

Dlaczego konieczne jest „zadeklarowanie” interfejsu jako abstrakcyjne?

To nie jest.

public abstract interface Interface {
       \___.__/
           |
           '----> Neither this...

    public void interfacing();
    public abstract boolean interfacing(boolean really);
           \___.__/
               |
               '----> nor this, are necessary.
}

Interfejsy i ich metody są niejawne, abstracta dodanie tego modyfikatora nie ma znaczenia.

Czy istnieją inne reguły dotyczące abstrakcyjnego interfejsu?

Nie, obowiązują te same zasady. Metoda musi zostać zaimplementowana przez dowolną (konkretną) klasę implementacyjną.

Jeśli streszczenie jest przestarzałe, dlaczego jest zawarte w Javie? Czy istnieje historia abstrakcyjnego interfejsu?

Interesujące pytanie. Odkopałem pierwsze wydanie JLS i nawet tam napisano: „Ten modyfikator jest przestarzały i nie powinien być używany w nowych programach Java” .

Dobra, kopanie jeszcze dalej ... Po trafieniu w wiele zepsutych linków udało mi się znaleźć kopię oryginalnej specyfikacji Oak 0.2 (lub „instrukcji”). Dość ciekawa lektura, muszę powiedzieć, i tylko 38 stron! :-)

W sekcji 5 Interfejsy zawiera następujący przykład:

public interface Storing {
    void freezeDry(Stream s) = 0;
    void reconstitute(Stream s) = 0;
}

I na marginesie jest napisane

W przyszłości część „= 0” metod deklarowania w interfejsach może zniknąć.

Zakładając, że =0zostało zastąpione abstractsłowem kluczowym, podejrzewam, że abstractw pewnym momencie było to obowiązkowe dla metod interfejsu!


Artykuł pokrewny: Java: Abstrakcyjne interfejsy i abstrakcyjne metody interfejsu

aioobe
źródło
3
ale samo streszczenie nie jest przestarzałe, czy? Jest przestarzały dla interfejsów, ale wciąż istnieją abstrakcyjne klasy i metody.
user85421,
Dzięki ;-) Wydaje mi się, że w końcu udało mi się ustalić pochodzenie, nawet pozwalając abstractprzed metodami interfejsu.
aioobe,
13
Łał. Jest więc przestarzały „z założenia”. Ci projektanci JLS zawsze tak bardzo bali się zepsuć coś, a nawet zepsuć rzeczy, które nigdy nie zostały wydane ... :-)
Lukas Eder
@ aioobe, musisz być robotem indeksującym Google, o którym nie wiemy ... lol
Buhake Sindi
18
Btw. „public” nie jest również konieczne w przypadku metod w deklaracji interfejsu ... zawsze są one publiczne.
rec
37

Nie jest konieczne, jest opcjonalne, podobnie jak publicw przypadku metod interfejsu.

Zobacz JLS na ten temat:

http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html

9.1.1.1 abstrakcyjne interfejsy Każdy interfejs jest domyślnie abstrakcyjny. Ten modyfikator jest przestarzały i nie powinien być używany w nowych programach.

I

9.4 Deklaracje metod abstrakcyjnych

[...]

W celu zachowania zgodności ze starszymi wersjami platformy Java dozwolone, ale odradzane jest, ze względu na styl, nadmiarowe określanie abstrakcyjnego modyfikatora dla metod zadeklarowanych w interfejsach.

Dozwolone jest, ale zdecydowanie odradzane ze względu na styl, nadmiarowe określanie publicznego modyfikatora metod interfejsu.

Lukas Eder
źródło
7
do JLS: Dozwolone jest, ale zdecydowanie odradzane, ze względu na styl, redundantne pisanie dwóch zdań o tym samym znaczeniu i prawie dokładnym sformułowaniu obok siebie ...
n611x007
11

Nie jest konieczne deklarowanie streszczenia interfejsu.

Podobnie jak zadeklarowanie wszystkich tych metod jako publiczne (które już są, jeśli interfejs jest publiczny) lub abstrakcyjne (które już są w interfejsie) są zbędne.

Jednak nikt cię nie powstrzymuje.

Inne rzeczy, które możesz wyraźnie określić, ale nie musisz:

  • wywołaj super () w pierwszym wierszu konstruktora
  • extends Object
  • implementować odziedziczone interfejsy

Czy istnieją inne reguły dotyczące abstrakcyjnego interfejsu?

Interfejs jest już „abstrakcyjny”. Ponowne użycie tego słowa kluczowego nie ma absolutnie żadnej różnicy.

Thilo
źródło
2
Najwyraźniej metody są nawet publiczne, jeśli sam interfejs jest prywatny.
Thilo,
7

Pamiętaj, że wiosną ma to znaczenie nieakademickie. Abstrakcyjny interfejs jest ostrzeżeniem dla dewelopera, aby go nie używać @Autowired. Mam nadzieję, że spring / eclipse @Autowiredprzyjrzy się temu atrybutowi i ostrzeże / nie powie o jego użyciu.

Prawdziwy przykład: @Service proxy w @Transnational do @Repository musi używać tych samych podstawowych metod, jednak powinny one używać różnych interfejsów, które rozszerzają ten abstrakcyjny interfejs z powodu @Autowired. (Nazywam ten interfejs XXXSpec)

Adi Lev
źródło
+1 dobre trafienie, rozejrzałem się szeroko za rozdzieleniem niepasujących zastrzyków sesji. Może mogę użyć findbugs / checkstyle dla reguły ....
Grim
3

Każdy interfejs jest domyślnie abstrakcyjny.
Ten modyfikator jest przestarzały i nie powinien być używany w nowych programach.

[Specyfikacja języka Java - 9.1.1.1 abstractInterfejsy]

Należy również pamiętać, że metody elementów interfejsu są niejawne public abstract.
[Specyfikacja języka Java - 9.2 Członkowie interfejsu]

Dlaczego te modyfikatory są ukryte? Nie ma innego modyfikatora (nawet „ modyfikatora bez modyfikatora ”), który byłby tutaj przydatny, więc nie musisz go wyraźnie wpisywać.

kapex
źródło
2

To nie jest konieczne. To dziwactwo języka.

Czeski
źródło
2

Nie jest to konieczne, ponieważ interfejsy są domyślnie abstrakcyjne, ponieważ wszystkie metody interfejsu są abstrakcyjne.

Swagatika
źródło
-2

Abstrakcyjny interfejs nie jest tak zbędny, jak się wydaje, przynajmniej wszyscy twierdzą.

Interfejs można rozszerzyć, tak jak klasa. Jeśli projektujesz hierarchię interfejsu dla swojej aplikacji, możesz mieć interfejs „podstawowy”, rozszerzasz inne interfejsy, ale nie chcesz sam jako obiekt.

Przykład:

public abstract interface MyBaseInterface {
    public String getName();
}

public interface MyBoat extends MyBaseInterface {
    public String getMastSize();
}

public interface MyDog extends MyBaseInterface {
    public long tinsOfFoodPerDay();
}

Nie chcesz, aby klasa implementowała MyBaseInterface, tylko dwa pozostałe, MMyDog i MyBoat, ale oba interfejsy współużytkują interfejs MyBaseInterface, więc mają właściwość „name”.

Wiem, że to trochę akademickie, ale pomyślałem, że niektórzy mogą uznać to za interesujące. :-)

W tym przypadku jest to po prostu „marker”, sygnalizujący implementatorom interfejsu, że nie został zaprojektowany do samodzielnego wdrożenia. Powinienem wskazać kompilator (przynajmniej sun / ora 1.6, z którym go wypróbowałem) kompiluje klasę, która implementuje abstrakcyjny interfejs.

Eurospoofer
źródło
3
Uważam, że całkowicie źle zrozumiałeś moje pytanie.
Buhake Sindi
3
Nie zgadzam się z tym rozumowaniem. Myślę, że każdy interfejs musi zapewniać w pełni funkcjonalny zestaw funkcji, dlatego też każdy interfejs można wdrożyć samodzielnie. Nie byłoby też powodu, aby kompilator odmawiał kompilacji klasy implementującej interfejs wyraźnie zadeklarowany jako abstrakcyjny, ponieważ wszystkie interfejsy są już domyślnie abstrakcyjne. To całkowicie zmieniłoby znaczenie słowa kluczowego „abstrakcyjnego”.
BladeCoder
-3

Cóż, „Abstract Interface” to konstrukcja leksykalna: http://en.wikipedia.org/wiki/Lexical_analysis .

Jest to wymagane przez kompilator, możesz także pisać interface.

Cóż, nie wtrącaj się zbytnio w konstrukcję leksykalną języka, ponieważ mogliby go tam umieścić, aby rozwiązać pewne niejasności kompilacji, które określa się jako specjalne przypadki podczas procesu kompilacji lub dla pewnej kompatybilności wstecznej, spróbuj skupić się na podstawowej konstrukcji leksykalnej.

Istotą `interfejsu jest uchwycenie pewnej abstrakcyjnej koncepcji (idea / myśl / myślenie wyższego rzędu itp.), Której implementacja może się różnić ... to znaczy, może istnieć wiele implementacji.

Interfejs to czysty abstrakcyjny typ danych, który reprezentuje cechy obiektu, który przechwytuje lub reprezentuje.

Funkcje mogą być reprezentowane przez przestrzeń lub czas. Gdy są reprezentowane przez przestrzeń (pamięć), oznacza to, że Twoja konkretna klasa zaimplementuje pole i metodę / metody, które będą działały na tym polu lub przez czas, co oznacza, że ​​zadanie implementacji tej funkcji ma charakter czysto obliczeniowy (wymaga więcej zegarów procesora do przetwarzania), więc masz kompromis między przestrzenią a czasem na wdrożenie funkcji.

Jeśli twoja konkretna klasa nie implementuje wszystkich funkcji, ponownie staje się abstrakcyjna, ponieważ masz implementację swojej myśli, idei lub abstrakcyjności, ale nie jest kompletna, określasz ją przez abstract klas.

Konkretna klasa będzie klasą / zestawem klas, które w pełni uchwycą abstrakcyjność, którą próbujesz uchwycić klasę XYZ.

Więc wzór jest

Interface--->Abstract class/Abstract classes(depends)-->Concrete class
Manish
źródło
1
Ta odpowiedź w ogóle nie odpowiada na moje pytanie. Również "It seams like you are new to Java. Naprawdę?
Buhake Sindi
„streszczenie jest przestarzałe”
Manish
(1) „streszczenie jest przestarzałe” -> jeśli go usuną, a kompilator przestanie go rozpoznawać, to poprzednia wersja kodu źródłowego używająca „interfejsu abstrakcyjnego” nie będzie kompilowana w nowszej wersji. Muszą zachować zgodność wsteczną. Kiedy definiujesz interfejs abstrakcyjny, znaczenie słowa kluczowego interfejsu jest zablokowane wraz z jego „abstrakcją”, co jest o wiele bardziej przejrzystą wersją, jednak dla doświadczonych programistów takich jak ty udostępnili skrót „interfejs” .. twoje pytanie jest podobne do i = i + 1 == > i ++ .. wybór należy do Ciebie: D
Manish,
Spójrz na zaakceptowaną odpowiedź. Wiem, że abstractinterfejs jest przestarzały. Chciałem wiedzieć, dlaczego wciąż jest akceptowalny i jaka jest historia abstractinterfejsu. Dajesz mi przewodnik Java 101 na temat abstrakcyjnego interfejsu.
Buhake Sindi
To nie jest konstrukcja leksykalna. To jest składnia. Semantycznie jest zbędny. Nie jest to „wymagane przez kompilator”. Część o czasoprzestrzeni to po prostu bzdura. Żaden z tych nonsensów nie odpowiada na zadane pytanie. Nie używaj formatowania kodu dla tekstu, który nie jest kodem.
Markiz Lorne