Menu
Coddy logo textTech

Metody abstrakcyjne w cechach

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

Trait mogą udostępniać gotowe do użycia metody, ale czasami potrzebujesz, aby klasa korzystająca z traitu zaimplementowała określoną funkcjonalność. Właśnie wtedy przydają się metody abstrakcyjne w traitach — definiują one kontrakt, który musi spełnić klasa korzystająca z traitu.

Gdy cecha deklaruje metodę abstrakcyjną, każda klasa używająca tej cechy musi ją zaimplementować:

<?php
trait Notifiable {
    abstract public function getEmail(): string;
    
    public function sendNotification(string $message): void {
        echo "Sending to " . $this->getEmail() . ": $message";
    }
}

class User {
    use Notifiable;
    
    public function __construct(private string $email) {}
    
    public function getEmail(): string {
        return $this->email;
    }
}

$user = new User("john@example.com");
$user->sendNotification("Welcome!");

Wynik:

Sending to john@example.com: Welcome!

Trait udostępnia metodę sendNotification(), ale wymaga, aby klasa zaimplementowała getEmail(). Tworzy to potężny wzorzec, w którym trait obsługuje wspólną logikę, a szczegóły specyficzne dla klasy deleguje do klasy implementującej.

Jeśli klasa używa cechy bez implementowania metody abstrakcyjnej, PHP zgłasza błąd krytyczny. Dzięki temu cechy mogą bezpiecznie polegać na istnieniu określonych metod, co sprawia, że kod jest bardziej przewidywalny i łatwiejszy w utrzymaniu.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system ustalania cen, w którym różne typy produktów obliczają ceny końcowe na różne sposoby, ale korzystają ze wspólnej logiki rabatów dzięki traitowi z metodą abstrakcyjną.

Rozmieścisz kod w trzech plikach:

  • Discountable.php: Utwórz trait o nazwie Discountable, który zapewnia funkcjonalność rabatów. Trait powinien zawierać:
    • Metodę abstrakcyjną getBasePrice(): float, którą muszą implementować klasy korzystające z tego traitu
    • Metodę applyDiscount(int $percent), która oblicza i zwraca cenę po zastosowaniu procentowego rabatu do ceny bazowej
    • Metodę getFinalPrice(int $percent), która zwraca sformatowany ciąg znaków: "Final price: $[discounted_price]" z 2 miejscami po przecinku
    Trait obsługuje wszystkie obliczenia rabatu, ale polega na każdej klasie, która przekazuje mu informację o cenie bazowej.
  • Product.php: Utwórz klasę Product, która korzysta z traitu Discountable. Dołącz plik z traitem. Użyj promocji konstruktora, aby zdefiniować prywatne $name (string) i prywatne $price (float). Zaimplementuj wymaganą metodę getBasePrice(), aby zwracała cenę produktu.
  • main.php: Dołącz plik Product. Otrzymasz trzy dane wejściowe: nazwę produktu, cenę i procentowy rabat. Utwórz instancję Product i wypisz dwa wiersze:
    • Cenę bazową sformatowaną jako "Base: $[price]" z 2 miejscami po przecinku
    • Wynik wywołania getFinalPrice() z procentowym rabatem

Ten wzorzec jest przydatny, ponieważ z traitu Discountable może korzystać dowolna klasa — produkty, usługi, subskrypcje — o ile implementuje getBasePrice(). Trait zapewnia wspólną logikę rabatów, a każda klasa określa, skąd pochodzi jej cena bazowa.

Spróbuj swoich sił

<?php

require_once 'Product.php';

// Odczytaj dane wejściowe
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$discountPercent = intval(trim(fgets(STDIN)));

// TODO: Utwórz instancję Product z nazwą i ceną

// TODO: Wyświetl cenę podstawową w formacie "Base: $[price]" z 2 miejscami po przecinku

// TODO: Wyświetl wynik wywołania getFinalPrice() z procentem rabatu

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