Podstawowe techniki OOP

Dziedziczenie

Dziedziczenie implementacji:

  • Definiuje implementację obiektu w kategoriach implementacji innego obiektu

  • Jest to mechanizm do współdzielenia kodu i reprezentacji

  • Dziedziczenie implementacji lub klas można aproksymować dziedziczeniem prywatnym

Dziedziczenie interfejsu:

  • Określa, kiedy jeden obiekt może być używany zamiast drugiego

  • Standardowym sposobem dziedziczenia interfejsu w C++ jest publiczne dziedziczenie po klasie, która ma (czysto) wirtualne funkcje składowe (można aproksymować dziedziczeniem publicznym po czysto abstrakcyjnych klasach)

Operowanie na obiektach wyłącznie w kategoriach interfejsu zdefiniowanego przez klasę abstrakcyjną ma dwie zalety:

  • Klienci pozostają nieświadomi specyficznego typu używanych przez siebie obiektów, o ile tylko te obiekty zachowują oczekiwany przez klientów interfejs.

  • Klienci pozostają nieświadomi klas implementujących te obiekty. Znają tylko klasę abstrakcyjną definiującą ten interfejs.

Wady dziedziczenia klas:

  • Jest statyczne – nie można w czasie działania programu zmienić implementacji odziedziczonych po klasie bazowej, ponieważ dziedziczenie jest definiowane w czasie kompilacji

  • Narusza enkapsulację – ujawnia klasie pochodnej szczegóły implementacji jej klas bazowych

  • Zależności implementacyjne mogą powodować problemy przy próbie ponownego użycia klasy pochodnej

Rozwiązaniem jest dziedziczenie jedynie po klasach abstrakcyjnych nie posiadających implementacji.

Składanie obiektów

Składanie obiektów (kompozycja):

  • Utworzenie nowego typu obiektu poprzez złożenie innych już istniejących typów obiektów

  • Jest definiowane dynamicznie podczas wykonywania programu za pośrednictwem obiektów, które pozyskują odwołania (referencje, odniesienia) do innych obiektów

  • Nie prowadzi do naruszenia enkapsulacji, ponieważ dostęp do obiektów jest możliwy jedynie poprzez ich interfejsy

Zalety składania obiektów:

  • Preferowanie składania obiektów zamiast dziedziczenia klas ułatwia podtrzymywanie hermetyzacji klas i pomaga ukierunkować klasy na pojedyncze zadania

  • Klasy i ich hierarchie pozostają niewielkie

Delegowanie

  • Bardziej uniwersalny od dziedziczenia sposób rozszerzania zachowania klasy

  • Dwa obiekty są zaangażowane w obsługę żądania: obiekt przyjmujący żądanie przekazuje operacje swojemu delegatowi

  • Ułatwia składanie zachowań w czasie wykonywania programu i zmienianie sposobu, w jaki są one składane

_images/Delegacja.png

Wada delegowania – dynamiczne, wysoce sparametryzowane oprogramowanie jest trudniej zrozumieć niż oprogramowanie bardziej statyczne.