Źródło: FreeCodeCamp Java to jeden z najpopularniejszych obecnie używanych obiektowych języków programowania. Ponieważ jest niezależny od platformy, aplikacje Java można znaleźć na każdym typie urządzenia i każdym systemie operacyjnym. A ponieważ Java jest stosunkowo łatwa do nauczenia, jest to jeden z języków, który zna wielu programistów. Ważną cechą języka Java, z którą powinieneś się zapoznać, jest dziedziczenie klas. Dziedziczenie pozwala zoptymalizować kod, ułatwiając ponowne wykorzystanie klas. Kiedy możesz ponownie wykorzystać kod, który został już przetestowany i zdebugowany, cykl życia oprogramowania staje się krótszy i tańszy. Chociaż w teorii jest to prosta koncepcja, kodowanie relacji dziedziczenia wymaga dbałości o szczegóły. Zwłaszcza w odniesieniu do dziedziczenia wielokrotnego, gdzie jedna klasa podrzędna dziedziczy właściwości z wielu klas nadrzędnych. Java odrzuca relacje wielokrotnego dziedziczenia, ponieważ powodują one niejednoznaczność, ale istnieje kilka sposobów na osiągnięcie wielu takich samych efektów, jeśli wiesz, co robić. W tym artykule przyjrzymy się problemom związanym z dziedziczeniem wielokrotnym i omówimy alternatywne opcje kodowania w Javie.
Terminologia dotycząca dziedziczenia
Czasami, aby odnieść sukces jako programista, musisz umieć rozwiązywać problemy i znajdować obejścia typowych błędów i problemów. Jest to istotna część bezpiecznego i inteligentnego kodowania. Jeden z takich problemów jest związany z wielokrotnym dziedziczeniem (a raczej jego brakiem) w Javie. Aby w pełni zrozumieć dziedziczenie w Javie, musisz znać podstawową terminologię dotyczącą dziedziczenia w programowaniu obiektowym (OOP).- Klasy są podstawową strukturą wzorców w obiektowych językach programowania. Klasa definiuje wspólne właściwości grupy obiektów.
- Klasa nadrzędna : znana również jako klasy bazowe lub superklasy. Klasa nadrzędna jest klasą rozszerzalną, która zapewnia funkcjonalność klasie podrzędnej. Pozwala na ponowne wykorzystanie. Definicje i funkcje klasy nadrzędnej są ponownie wykorzystywane podczas tworzenia klas podrzędnych.
- Klasa podrzędna : bardziej ogólnie nazywana podklasą, klasa podrzędna dziedziczy funkcjonalność z innej klasy. Klasy podrzędne są klasami rozszerzonymi lub pochodnymi.
- Dziedziczenie : Relacja pomiędzy klasami nadrzędnymi i podrzędnymi.
Typy dziedziczenia OOP
Obecnie w użyciu jest wiele popularnych obiektowych języków programowania, w tym Java, C++, JavaScript, Python, PHP, Ruby i Perl. Chociaż dziedziczenie jest powszechną koncepcją w tych językach OOP, nie wszystkie typy dziedziczenia istnieją w każdym z tych języków. Niezwykle ważna jest znajomość powszechnych rodzajów dziedziczenia i ograniczeń dziedziczenia w konkretnym języku, którego używasz. Im więcej wiesz o dziedziczeniu, tym skuteczniejszym programistą się staniesz. Rodzaje dziedziczenia obsługiwane przez Javę obejmują:- Dziedziczenie jednopoziomowe : gdy klasa podrzędna dziedziczy funkcje z pojedynczej klasy nadrzędnej.
- Dziedziczenie wielopoziomowe : Jest to wielopoziomowa forma dziedziczenia jednopoziomowego. W przypadku dziedziczenia wielopoziomowego klasa podrzędna może również pełnić funkcję klasy nadrzędnej dla innych klas podrzędnych. Zależność pomiędzy każdym poziomem jest liniowa – żadne gałęzie nie wznoszą się wyżej niż w przypadku dziedziczenia wielokrotnego. W tym przypadku ostatnia klasa potomna zawiera funkcje ze wszystkich poziomów powyżej.
- Dziedziczenie hierarchiczne : przeciwieństwo dziedziczenia wielokrotnego. W dziedziczeniu hierarchicznym pojedyncza klasa nadrzędna ma więcej niż jedną klasę podrzędną. Zamiast mieć gałęzie nad sobą, rozgałęzia się poniżej.
- Dziedziczenie hybrydowe : Jak sama nazwa wskazuje, dziedziczenie hybrydowe to połączenie innych typów dziedziczenia.
- Dziedziczenie wielokrotne : w przypadku dziedziczenia wielokrotnego klasa podrzędna ma więcej niż jedną klasę nadrzędną. Chociaż Java i JavaScript nie obsługują dziedziczenia wielokrotnego, języki OOP, takie jak C++, tak.
- Dziedziczenie wielościeżkowe : hybryda dziedziczenia wielokrotnego, wielopoziomowego i hierarchicznego. W przypadku dziedziczenia wielościeżkowego klasa potomna dziedziczy swoje cechy i funkcje od klasy nadrzędnej i kilku klas podrzędnych klasy nadrzędnej. Ponieważ dziedziczenie wielościeżkowe opiera się na dziedziczeniu wielokrotnym, Java nie obsługuje jego użycia.
Dlaczego Java nie obsługuje wielokrotnego dziedziczenia
Głównym problemem związanym z dziedziczeniem wielokrotnym jest to, że może ono powodować niejasności w klasach potomnych. W białej księdze z 1995 roku główny projektant Java James Gosling stwierdził, że problemy z wielokrotnym dziedziczeniem były jednym z powodów stworzenia Java. Złożoność nieodłącznie związana z dziedziczeniem wielokrotnym jest najwyraźniej widoczna w problemie diamentu. W problemie diamentu klasa nadrzędna A ma dwie różne klasy podrzędne B i C; to znaczy klasy potomne B i C rozszerzają klasę A. Teraz tworzymy nową klasę potomną D, która rozszerza zarówno klasę B, jak i klasę C. Zauważ, że mamy dziedziczenie wielokrotne (D rozszerza B i C), dziedziczenie hierarchiczne ( B i C rozszerzają A) i dziedziczenie wielopoziomowe (D rozszerza A, B i C). W przypadku problemu z diamentem klasy potomne B i C dziedziczą metodę z klasy nadrzędnej A. Zarówno B, jak i C zastępują dziedziczoną metodę. Ale nowe metody w B i C są ze sobą sprzeczne. Ostateczna klasa potomna D dziedziczy dwie niezależne i sprzeczne metody od swoich wielokrotnych rodziców B i C. Nie jest jasne, która metoda klasy D powinna zostać zastosowana, co powoduje niejasność. Inne języki programowania OOP wdrażają różne metody rozwiązywania niejednoznaczności wielokrotnego dziedziczenia.Jak rozwiązać problem wielokrotnego dziedziczenia w Javie
To, że dziedziczenie wielokrotne jest problematyczne, nie oznacza, że jest bezużyteczne. Istnieje wiele sytuacji, w których możesz chcieć, aby jedna klasa miała funkcje z kilku innych klas. Pomyśl tylko o Tesli Roadster, którą kupisz, gdy odniesiesz ogromny sukces jako programista. Jego parametry techniczne opierają się zarówno na klasie samochodu sportowego, jak i klasie pojazdu elektrycznego. Inny przykład: przeglądarka, przez którą czytasz ten artykuł. Posiada funkcje z klasy rozwiązań dotyczących prywatności w Internecie i z ogólnej klasy przeglądarek internetowych. Ale nie można rozszerzać wielu klas w Javie. Jak zatem ten język radzi sobie z problemem wielokrotnego dziedziczenia? Java wykorzystuje struktury zwane interfejsami. Interfejsy to typy abstrakcyjne, które definiują zachowanie, które ma być implementowane przez klasy. Ponieważ są abstrakcyjne, interfejsy nie zawierają szczegółowych instrukcji dotyczących ich zachowania. Zamiast tego klasy zapewniają konkretne implementacje zachowań interfejsu. Interfejsy mają kilka charakterystycznych cech:- W przeciwieństwie do klas, nie tworzy się instancji interfejsów. Zamiast tego klasy implementują interfejsy.
- Interfejsy zawierają tylko publiczne definicje stałych i nagłówki metod.
- Interfejsy mogą rozszerzać jedynie inne interfejsy, a nie klasy.
- Interfejsy mogą rozszerzać wiele interfejsów, a klasy mogą implementować wiele interfejsów.
GO TO FULL VERSION