Dlaczego Java 8 nie zezwala na domyślne metody Niepubliczne?

Weźmy przykład:

public interface Testerface {

    default public String example() {
        return "Hello";
    }

}

public class Tester implements Testerface {

    @Override
    public String example() {
        return Testerface.super.example() + " world!";
    }


}

public class Internet {

    public static void main(String[] args) {
        System.out.println(new Tester().example());
    }

}

Wystarczy, że to wydrukuje Hello world!. Ale powiedzmy, że robiłem coś innego z wartością zwracaną Testerface#example, na przykład inicjalizowałem plik danych i zwracałem wrażliwą wewnętrzną wartość, która nie powinna opuszczać klasy implementującej. Dlaczego Java nie zezwala na modyfikatory dostępu w domyślnych metodach interfejsu? Dlaczego nie mogą być chronione / prywatne i potencjalnie podwyższone przez podklasę (podobnie jak klasa, która rozszerza rodzica klasa może użyć bardziej widocznego modyfikatora dla nadpisanej metody)?

Powszechnym rozwiązaniem jest przejście do klasy abstrakcyjnej, jednak w moim konkretnym przypadku, mam interfejs dla enums, więc to nie ma zastosowania tutaj. Wyobrażam sobie, że albo przeoczono, albo dlatego, że pierwotna idea interfejsów mówi, że są "kontraktem" dostępnych metod, ale przypuszczam, że chcę się dowiedzieć, co się z tym dzieje.

Przeczytałem " dlaczego "final" nie jest dozwolone w metodach interfejsu Java 8?", który stwierdza:

Podstawową ideą metody domyślnej jest: jest to metoda interfejsu z domyślną implementacją, a klasa pochodna może dostarczyć bardziej szczegółową implementację

I wydaje mi się, że widoczność w ogóle nie złamałaby tego aspektu.

Podobnie jak w przypadku pytania połączonego, ponieważ wygląda na to, że miało problem z zamknięciem, autorytatywna odpowiedź byłaby mile widziana w tej sprawie, a nie opiniotwórczych.

Author: Community, 2014-12-08

1 answers

Jak widzieliśmy w Jaki jest powód, dla którego "synchronizacja" nie jest dozwolona w metodach interfejsu Java 8? i Dlaczego "final" nie jest dozwolone w metodach interfejsu Java 8? Rozszerzanie interfejsów w celu zdefiniowania zachowania jest bardziej subtelne, niż mogłoby się początkowo wydawać. Okazuje się, że każdy z możliwych modyfikatorów ma swoją własną historię; nie jest to po prostu kwestia ślepego kopiowania z działania klas. (Jest to co najmniej oczywiste z perspektywy czasu, jako narzędzia do modelowania OO, które działają dla pojedynczych dziedziczenie nie działa automatycznie w przypadku dziedziczenia wielokrotnego.)

Zacznijmy od oczywistej odpowiedzi: interfaces have always been restricted to only have public members, and while we added default methods and static methods to interfaces in Java 8, that doesn 't mean we have to change everything just to be "more like" classes.

W przeciwieństwie do synchronized i final, które byłyby poważnymi błędami w obsłudze domyślnych metod, słabsze możliwości, szczególnie prywatne, są rozsądne funkcje do rozważenia. Prywatne metody interfejsu, zarówno statyczne, jak i instancyjne (zauważ, że nie są to domyślne metody, ponieważ nie uczestniczą w dziedziczeniu) są doskonałym narzędziem (chociaż mogą być łatwo symulowane przez Niepubliczne klasy pomocnicze.)

W rzeczywistości rozważaliśmy użycie prywatnych metod interfejsu w Javie 8; było to głównie coś, co spadło z dolnej części listy z powodu ograniczeń zasobów i czasu. Jest całkiem możliwe, że ta funkcja może pojawić się ponownie na liście zadań pewnego dnia. (Aktualizacja: prywatne metody w interfejsach zostały dodane w Javie 9.)

Metody pakietowe i chronione są jednak bardziej skomplikowane, niż wyglądają; złożoność wielokrotnego dziedziczenia i złożoność prawdziwego znaczenia protected oddziaływałyby na różnego rodzaju niefajne sposoby. Więc nie wstrzymywałbym twojego oddechu.

Krótka odpowiedź brzmi: prywatne metody interfejsu to coś, co moglibyśmy zrobić w 8, ale my nie mógł zrobić wszystkiego, co można było zrobić i nadal wysyłać, więc został wycięty, ale mógł wrócić.

 46
Author: Brian Goetz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-10 16:26:53