Start · Sprachen · PHP · Kapitel · Objektorientierung
// Kapitel · PHP

Objektorientierung

PHP hat ein vollwertiges OOP-System mit Klassen, Interfaces, Traits, abstrakten Klassen und seit PHP 8.2 auch readonly-Klassen.

Kurzantwort
Objektorientierung in PHP — kurz erklärt

PHP ist eine vollwertige objektorientierte Sprache: Klassen, Interfaces, Traits, Enums (seit 8.1), Vererbung, Konstanten, abstrakte Klassen, readonly-Properties (8.1) und readonly-Klassen (8.2). Attribute (seit 8.0) ersetzen DocBlock-Annotationen. Zugriffs-Modifier: public, protected, private; seit 8.4 auch private(set) und protected(set).

Klasse mit Konstruktor-Property-Promotion (PHP 8.0+)

<?php

declare(strict_types=1);

final class Product
{
    public function __construct(
        public readonly string $name,
        public readonly float $price,
        private int $stock = 0,
    ) {}

    public function increaseStock(int $amount): void
    {
        $this->stock += $amount;
    }

    public function isAvailable(): bool
    {
        return $this->stock > 0;
    }
}

$p = new Product('T-Shirt', 24.90);
$p->increaseStock(50);
echo $p->name;      // T-Shirt (public readonly)
// $p->name = 'x'; // Error: Cannot modify readonly property

Vererbung

class Animal
{
    public function __construct(public string $name) {}

    public function speak(): string
    {
        return "$this->name macht Geräusche";
    }
}

class Dog extends Animal
{
    public function speak(): string
    {
        return "$this->name bellt";
    }
}

$d = new Dog('Bello');
echo $d->speak();   // Bello bellt

Interfaces

interface PaymentGateway
{
    public function charge(int $amountInCents, string $currency): bool;
    public function refund(string $transactionId): bool;
}

final class StripeGateway implements PaymentGateway
{
    public function charge(int $amountInCents, string $currency): bool { /* ... */ }
    public function refund(string $transactionId): bool { /* ... */ }
}

Abstrakte Klassen

Können nicht instanziiert werden. Erzwingen, dass Kinder bestimmte Methoden implementieren, teilen aber gemeinsamen Code:

abstract class Report
{
    public function generate(): string
    {
        $data = $this->collect();
        return $this->format($data);
    }

    abstract protected function collect(): array;
    abstract protected function format(array $data): string;
}

Traits — horizontale Wiederverwendung

PHP hat keine Mehrfachvererbung. Traits sind der Ersatz: Methoden-Bausteine, die in mehrere Klassen eingemischt werden:

trait Loggable
{
    public function log(string $msg): void
    {
        error_log('[' . static::class . '] ' . $msg);
    }
}

class User { use Loggable; }
class Order { use Loggable; }

(new User)->log('Registriert');    // [User] Registriert

Statische Methoden & Properties

class Config
{
    private static array $data = [];

    public static function set(string $key, mixed $value): void
    {
        self::$data[$key] = $value;
    }

    public static function get(string $key): mixed
    {
        return self::$data[$key] ?? null;
    }
}

Config::set('app.name', 'programmierung.net');
echo Config::get('app.name');

Readonly-Klassen (PHP 8.2+)

Alle Properties sind implizit readonly. Ideal für Value Objects und DTOs:

final readonly class Money
{
    public function __construct(
        public int $cents,
        public string $currency,
    ) {}

    public function plus(Money $other): Money
    {
        return new Money($this->cents + $other->cents, $this->currency);
    }
}

Häufige Fragen

Wann nutze ich ein Interface, wann eine abstrakte Klasse?

Interface: Vertrag ohne Implementierung — eine Klasse kann viele implementieren. Abstrakte Klasse: teilweise Implementierung + abstract-Methoden; nur eine Elternklasse. Faustregel: Verhalten → Interface, Gerüst → Abstract.

Was sind Traits und wann sind sie sinnvoll?

Traits enthalten Methoden und Properties, die in Klassen "eingemischt" werden (use TraitName;). Lösen Mehrfachvererbung ohne Diamond-Problem. Typisch: Logging, Cacheable, HasUuid in Laravel-Models.

Was macht <code>readonly</code> bei Properties?

public readonly int $id; erlaubt genau eine Zuweisung — meist im Konstruktor. Danach wirft jeder Set-Versuch eine Error. Perfekt für Value-Objects. Seit 8.2 auch für die ganze Klasse: final readonly class.

Was sind Enum-Typen?

Seit PHP 8.1: enum Status { case Active; case Inactive; }. Mit Werten als Backed-Enum: enum Status: string { case Active = "active"; }. Enum-Cases sind Singletons — gleicher Wert heißt gleiche Instanz.

Wie funktioniert Dependency Injection in PHP?

Abhängigkeiten werden im Konstruktor als typisierte Parameter deklariert (public function __construct(private LoggerInterface $log) {}, Constructor Property Promotion seit 8.0). Ein DI-Container (z.B. der Laravel-Service-Container) löst sie automatisch auf.