Dziedziczenie a kompozycja — kompromisy
Porównaj dziedziczenie i kompozycję oraz wybierz właściwe rozwiązanie projektowe
Dziedziczenie a kompozycja — kompromisy to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.
Dwa sposoby ponownego użycia kodu
Kod można ponownie wykorzystać, dziedzicząc po innej klasie albo komponując go jako składową. Oba podejścia mają swoje zastosowania.
Dziedziczenie: „jest”
Dziedziczenie należy stosować, gdy klasa pochodna rzeczywiście jest szczególnym rodzajem klasy bazowej.
class Vehicle {};
class Car : public Vehicle {}; // a Car IS a Vehicle
class SportsCar : public Car {};Kompozycja: „ma”
Kompozycję należy stosować, gdy relacja ma charakter „ma” lub „używa”.
class Engine {};
class Car {
Engine engine_; // a Car HAS an Engine
};Kompromis dotyczący sprzężenia
Dziedziczenie tworzy silne sprzężenie — klasy pochodne zależą od szczegółów implementacji klasy bazowej. Kompozycja pozwala zachować niezależność modułów i ułatwia ich modyfikowanie.
Elastyczność
Kompozycja pozwala zmieniać zachowanie w czasie wykonywania — można wymienić komponowany obiekt. Dziedziczenie wiąże zachowanie w czasie kompilacji.
class Logger {
std::unique_ptr<LogSink> sink_; // can swap implementations
public:
void setSink(std::unique_ptr<LogSink> s) { sink_ = std::move(s); }
};Testowanie
Obiekty komponowane można zastępować atrapami na potrzeby testów. Klasy bazowe używane przez dziedziczenie trudniej zastępować atrapami bez funkcji wirtualnych lub szablonów.
Problem kruchej klasy bazowej
Zmiany w klasie bazowej mogą zepsuć wiele klas pochodnych. Kompozycja ogranicza wpływ zmian do klasy, która jej używa.
Kiedy wybrać dziedziczenie
Dziedziczenie jest właściwe, gdy:
- istnieje wyraźna relacja typu „jest”
- potrzebny jest polimorfizm za pośrednictwem interfejsu bazowego
- klasa bazowa została jawnie zaprojektowana z myślą o dziedziczeniu
Kiedy wybrać kompozycję
Kompozycja jest właściwa, gdy:
- potrzebna jest elastyczność wymiany implementacji
- relacja ma charakter „ma” lub „używa”
- potrzebne jest słabe sprzężenie i łatwiejsze testowanie
Wzorzec Strategy
Połącz kompozycję z polimorfizmem: przechowuj wskaźnik do klasy bazowej wskazujący na obiekt strategii, który jest komponowany przez klasę używającą tej strategii.
class Sorter {
std::unique_ptr<SortStrategy> strategy_;
public:
void sort(std::vector<int>& v) { strategy_->execute(v); }
};Mixiny i klasy polityk
W celu dostosowywania w czasie kompilacji należy używać szablonowych klas polityk — jest to kompozycja na poziomie typów. To rozwiązanie jest elastyczne i nie powoduje narzutu w czasie wykonywania.
Interfejs i kompozycja
Typowy współczesny wzorzec polega na zdefiniowaniu interfejsu, czyli abstrakcyjnej klasy bazowej, i komponowaniu konkretnych klas, które go implementują. Dziedziczenie służy do definiowania interfejsu, a kompozycja do implementacji.
Szybki test
Które podejście zazwyczaj zapewnia większą elastyczność i słabsze sprzężenie?
Podsumowanie
Dziedziczenie modeluje relację „jest”, a kompozycja relację „ma”. Kompozycja jest bardziej elastyczna i zapewnia słabsze sprzężenie, dlatego należy preferować ją przy ponownym użyciu kodu. Dziedziczenie należy stosować do polimorfizmu za pośrednictwem interfejsu, często w połączeniu z komponowanymi implementacjami.
Często zadawane pytania
Czy lekcja „Dziedziczenie a kompozycja — kompromisy” jest bezpłatna?
Tak — pełny tekst „Dziedziczenie a kompozycja — kompromisy” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Dziedziczenie a kompozycja — kompromisy”?
Porównaj dziedziczenie i kompozycję oraz wybierz właściwe rozwiązanie projektowe Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C++ Academy?
Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Dziedziczenie a kompozycja — kompromisy”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?
Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Dziedziczenie pojedyncze i wielokrotne
- Funkcje wirtualne i vtable
- Klasy abstrakcyjne i czysto wirtualne metody
- Dziedziczenie a kompozycja — kompromisy