Menu
Coddy logo textTech

Kompozycja a dziedziczenie

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 56 z 91.

W poprzednim rozdziale dowiedziałeś się, że cechy zapewniają możliwość „ma”, podczas gdy dziedziczenie ustanawia relację „jest”. Kompozycja rozwija koncepcję „ma”, budując złożone obiekty z prostszych i przechowując je jako właściwości zamiast po nich dziedziczyć.

Przy dziedziczeniu Car może rozszerzać Vehicle. Przy kompozycji Car zawiera obiekt Engine:

<?php
class Engine {
    public function start(): string {
        return "Engine started";
    }
}

class Car {
    private Engine $engine;
    
    public function __construct() {
        $this->engine = new Engine();
    }
    
    public function start(): string {
        return $this->engine->start();
    }
}

$car = new Car();
echo $car->start();

Wynik:

Engine started

Klasa Car nie dziedziczy po Engine — posiada go. Takie podejście ma istotne zalety: możesz wymienić silnik na inną implementację, klasy pozostają luźno powiązane, a Ty unikasz sztywnych hierarchii tworzonych przez głębokie dziedziczenie.

Popularna zasada w OOP brzmi: „przedkładaj kompozycję nad dziedziczenie”. Dziedziczenie sprawdza się w przypadku rzeczywistych hierarchii typów (pies rzeczywiście jest zwierzęciem), ale kompozycja sprawdza się lepiej, gdy składasz funkcjonalność z niezależnych elementów. Możesz łączyć wiele obiektów, zastępować je w czasie działania programu i testować komponenty w izolacji.

W następnej lekcji omówimy wstrzykiwanie zależności, które rozwija kompozycję, umożliwiając kontrolowanie sposobu, w jaki obiekty otrzymują swoje zależności.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system komputerowy przy użyciu kompozycji, w której obiekt Computer składa się z osobnych obiektów komponentów, zamiast po nich dziedziczyć. To pokazuje, jak kompozycja pozwala budować złożone obiekty z prostszych, niezależnych części.

Rozmieścisz swój kod w trzech plikach:

  • Processor.php: Utwórz klasę Processor, która reprezentuje procesor. Użyj promocji właściwości konstruktora, aby zdefiniować prywatne $model (ciąg znaków) i prywatne $cores (liczbę całkowitą). Dodaj metodę getSpecs(), która zwraca "[model] ([cores] cores)".
  • Memory.php: Utwórz klasę Memory, która reprezentuje pamięć RAM. Użyj promocji właściwości konstruktora, aby zdefiniować prywatne $size (liczbę całkowitą reprezentującą GB). Dodaj metodę getCapacity(), która zwraca "[size]GB RAM".
  • main.php: Dołącz oba pliki komponentów i utwórz klasę Computer, która wykorzystuje kompozycję. Klasa Computer powinna:
    • Przechowywać obiekt Processor i obiekt Memory jako prywatne właściwości
    • Przyjmować w konstruktorze model procesora, liczbę rdzeni i rozmiar pamięci
    • Tworzyć obiekty komponentów wewnętrznie podczas konstruowania
    • Mieć metodę describe(), która zwraca "Computer with [processor specs] and [memory capacity]"

    Otrzymasz trzy dane wejściowe: model procesora, liczbę rdzeni i rozmiar pamięci w GB. Utwórz obiekt Computer o tych specyfikacjach i wypisz wynik wywołania describe().

Zwróć uwagę, że klasa Computer nie rozszerza klasy Processor ani Memory. Ona je zawiera. Ta relacja „ma” realizowana za pomocą kompozycji pozwala zachować niezależność i możliwość ponownego użycia każdego komponentu, a jednocześnie umożliwia klasie Computer delegowanie zadań do jej części w razie potrzeby.

Spróbuj swoich sił

<?php
require_once 'Processor.php';
require_once 'Memory.php';

class Computer
{
    // TODO: Zdefiniuj prywatne właściwości do przechowywania obiektów Processor i Memory

    // TODO: Konstruktor powinien przyjmować model procesora, liczbę rdzeni i rozmiar pamięci
    // oraz tworzyć wewnętrznie obiekty komponentów
    public function __construct()
    {
        // TODO: Utwórz obiekty Processor i Memory oraz zapisz je
    }

    // TODO: Zaimplementuj metodę describe(), która zwraca
    // "Computer with [processor specs] and [memory capacity]"
    public function describe(): string
    {
        // TODO: Wywołaj metody obiektów komponentów i zwróć sformatowany ciąg znaków
    }
}

// Odczytaj dane wejściowe
$processorModel = trim(fgets(STDIN));
$cores = intval(fgets(STDIN));
$memorySize = intval(fgets(STDIN));

// TODO: Utwórz obiekt Computer o podanych parametrach i wypisz wynik describe()

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online