Dlaczego Java nie obsługuje dziedziczenia prywatnego / chronionego, takiego jak C ++? [Zamknięte]

12

Podczas dziedziczenia klasy w C ++ użytkownik może określić specyfikator dostępu, taki jak:

class Base
{
    public int mem1;
    protected in mem2;
};

class Derived1 : **private** Base
{
    // mem1 will be private here.
    // mem2 will be private here.
};

class Derived2 : **protected** Base
{
    // mem1 will be protected here.
    // mem2 will be protected here.
};

class Derived2 : **public** Base
{
    // mem1 will be public here.
    // mem2 will be protected here.
};

Ale to samo nie jest możliwe w Javie, tzn. Rozszerzenie w java jest zawsze jak „publiczne” dziedziczenie w C ++.

Czy ktoś mógłby wyjaśnić przyczynę tego?

Rumit Parakhiya
źródło
16
Nie trzeba powodu, aby pomijać funkcję, potrzebujemy powodu (najlepiej kilku dobrych), aby ją dodać.
1
Można na to odpowiedzieć jedynie spekulacyjnie, głosując za zamknięciem.
Jimmy Hoffa

Odpowiedzi:

10

Większość korzyści płynących z dziedziczenia prywatnego / chronionego można łatwo osiągnąć poprzez enkapsulację. Thomas Eding podał kilka dobrych przykładów spraw, które mogłyby być łatwiejsze dzięki dodaniu dziedziczenia prywatnego / chronionego, i chociaż są to ważne przypadki, istnieją obejścia, które nie wymagają dziedziczenia prywatnego / chronionego i są bardziej „idiomatyczne” (w Javie pod adresem najmniej).

Twórcy języka Java najwyraźniej uważali, że złożoność kosztów potrzebnych do obsługi dziedziczenia prywatnego / chronionego (w tym dziedziczenia wielokrotnego) przeważa nad korzyściami, jakie przyniesie.

pswg
źródło
1
Warto zauważyć, że w C ++ istnieją pewne ważne różnice między prywatnym dziedziczeniem a włączeniem jako członka, ale dotyczą one kolejności inicjowania i wielokrotnego dziedziczenia, a zatem nie przekładają się na prostszy system obiektowy Java.
Jan Hudec
2
-1: „ Wszelkie korzyści wynikające z dziedziczenia prywatnego / chronionego można łatwo osiągnąć poprzez enkapsulację”. Źle. Zgodziłbym się z „ Najwięcej korzyści ...”
Thomas Eding
@ThomasEding Czy możesz podać przykład czegoś, co można osiągnąć poprzez dziedziczenie prywatne / chronione, ale nie poprzez enkapsulację (lub przynajmniej coś, co wymagałoby sporo pracy w enkapsulacji)? Szczerze mówiąc, nie mogę wymyślić żadnego z nich, ale jestem otwarty na przekonanie.
pswg
2
Ups, przepraszam za to. Oto kilka przykładów w C ++. (1) Załóżmy, że chcesz wewnętrznie uznać klasę Bza A( Bdziedziczy prywatnie A), abyś mógł polimorficznie używać jej w jakiejś metodzie. W przypadku kompozycji można to zrobić, ale jest to znacznie bardziej bałagan. W tym miejscu należy utworzyć oddzielną podklasę A'(prawdopodobnie klasę wewnętrzną), która implementuje używaną funkcjonalność. Będzie trzeba także ręcznie delegować zmian w nadrzędnej Bklasy ( Bsprawia, A'przyjaciela, A'przyjmuje odniesienie do B). Przypuszczam, że nie jest to zbyt trudne, ale powoduje bałagan w kodzie. (
Ciąg
2
... (2) Jeśli chcesz Buzyskać dostęp do zmiennych chronionych A, dziedziczenie prywatne jest łatwiejsze do wdrożenia w porównaniu z kompozycją. Dzięki kompozycji możesz zaimplementować A'podobnie jak powyżej i / lub zwiększyć dostęp do chronionych zmiennych. (3) Załóżmy, że chcesz mieć jedną wspólną statyczną zmienną składową, która jest dokładnie taką samą zmienną dla instancji szablonu. Rozwiązaniem jest prywatne dziedziczenie od nie bazującej na szablonie klasy bazowej, która ma element statyczny. Kompozycja nie może rozwiązać tego problemu, chociaż inne techniki mogłyby (np. Zaprzyjaźnić się z inną klasą z członkiem).
Thomas Eding
9

Ponieważ Java nie ma wielokrotnego dziedziczenia i wszystko musi zostać (publicznie) odziedziczone Object, nie ma w Javie miejsc, w których prywatne lub chronione dziedzictwo dałoby prawidłowy program.

Bart van Ingen Schenau
źródło