Menu
Coddy logo textTech

Klasy abstrakcyjne

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

Klasa abstrakcyjna to klasa, której nie można bezpośrednio instancjonować. Służy jako szablon dla innych klas i definiuje metody, które muszą implementować klasy potomne. Klasę abstrakcyjną tworzy się za pomocą słowa kluczowego abstract.

<?php
abstract class Shape {
    protected $color;
    
    public function __construct($color) {
        $this->color = $color;
    }
    
    abstract public function calculateArea();
    
    public function getColor() {
        return $this->color;
    }
}

class Rectangle extends Shape {
    private $width;
    private $height;
    
    public function __construct($color, $width, $height) {
        parent::__construct($color);
        $this->width = $width;
        $this->height = $height;
    }
    
    public function calculateArea() {
        return $this->width * $this->height;
    }
}

$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();

Wynik:

15

Klasa Shape deklaruje metodę abstrakcyjną calculateArea() bez podania jej implementacji. Każda klasa rozszerzająca Shape musi zaimplementować tę metodę. Zauważ, że klasy abstrakcyjne mogą również zawierać zwykłe metody, takie jak getColor(), które klasy potomne dziedziczą bezpośrednio.

Metody abstrakcyjne definiują, co musi robić klasa potomna, ale nie jak. Dzięki temu wszystkie kształty mają metodę calculateArea(), a każdy z nich może obliczać swoje pole w inny sposób.

Najważniejsza kwestia: Klasy abstrakcyjne łączą strukturę dziedziczenia z wymuszonymi wymaganiami. Używaj ich, gdy chcesz współdzielić kod między powiązanymi klasami, jednocześnie upewniając się, że każda klasa potomna implementuje określone metody.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system odtwarzacza multimediów, który pokazuje, jak klasy abstrakcyjne definiują kontrakt, jednocześnie pozwalając różnym typom mediów na własną implementację odtwarzania.

Rozmieścisz kod w trzech plikach:

  • Media.php: Zdefiniuj abstrakcyjną klasę Media, która będzie wzorcem dla wszystkich typów mediów. Powinna mieć chronioną właściwość $title oraz konstruktor, który przyjmuje i ustawia tytuł. Dodaj metodę abstrakcyjną o nazwie play(), którą muszą implementować klasy potomne. Dodaj też zwykłą metodę getTitle(), która zwraca tytuł. Ta konkretna metoda zostanie odziedziczona przez wszystkie klasy potomne.
  • Song.php: Zdefiniuj klasę Song, która rozszerza Media. Na początku pliku dołącz plik Media. Ta klasa dodaje właściwość $artist. Konstruktor powinien przyjmować tytuł i wykonawcę: użyj parent::__construct() dla tytułu, a następnie samodzielnie ustaw wykonawcę. Zaimplementuj wymaganą metodę play(), aby zwracała "Playing song: [title] by [artist]".
  • Podcast.php: Zdefiniuj klasę Podcast, która rozszerza Media. Na początku pliku dołącz plik Media. Ta klasa dodaje właściwość $episode (liczbę całkowitą). Konstruktor powinien przyjmować tytuł i numer odcinka: użyj parent::__construct() dla tytułu, a następnie ustaw odcinek. Zaimplementuj wymaganą metodę play(), aby zwracała "Playing podcast: [title] - Episode [episode]".

W pliku main.php dołącz pliki Song i Podcast. Otrzymasz cztery dane wejściowe: tytuł utworu, nazwę wykonawcy, tytuł podcastu i numer odcinka (jako ciąg znaków do konwersji na liczbę całkowitą). Utwórz obiekty Song i Podcast z tymi wartościami. Wyświetl wynik wywołania play() najpierw dla utworu, a następnie dla podcastu, każdy w osobnym wierszu.

To wyzwanie pokazuje, jak klasy abstrakcyjne definiują kontrakt: każdy typ mediów musi mieć metodę play(), ale każdy typ implementuje ją inaczej. Abstrakcyjnej klasy Media nie można bezpośrednio instancjonować; służy ona wyłącznie do zapewnienia struktury i wspólnych funkcjonalności klasom potomnym.

Spróbuj swoich sił

<?php
require_once 'Song.php';
require_once 'Podcast.php';

// Wczytaj dane wejściowe
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));

// TODO: Utwórz obiekt Song, używając songTitle i artistName

// TODO: Utwórz obiekt Podcast, używając podcastTitle i episodeNumber

// TODO: Wypisz wynik wywołania play() na obiekcie Song

// TODO: Wypisz wynik wywołania play() na obiekcie Podcast

?>
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