PHP 8: Modern PHP Development · Object-Oriented PHP 8

Interfaces, Abstract Classes and Traits

Model contracts and share behavior without deep inheritance hierarchies.

Create a free account to save this page, take notes and track your progress. Sign in

Interfaces define contracts (method signatures, constants); a class can implement many. Abstract classes share code and state while leaving some methods abstract; a class extends only one. Traits copy methods (and properties) into classes for horizontal reuse. Prefer interfaces plus composition; use abstract classes for template-method style shared behavior; use traits sparingly for small cross-cutting helpers. Since 8.2 traits can define constants, and since 8.3 class constants can be typed.

<?php
interface PaymentGateway
{
    public function charge(Money $amount, string $token): ChargeResult;
}

abstract class HttpGateway implements PaymentGateway
{
    public function __construct(protected readonly HttpClient $http) {}

    protected function post(string $url, array $body): array
    {
        return $this->http->post($url, ['json' => $body])->toArray();
    }
}

trait LogsCalls
{
    private function logCall(string $method, array $context = []): void
    {
        $this->logger->info("Calling {$method}", $context);
    }
}

final class StripeGateway extends HttpGateway
{
    use LogsCalls;

    public function __construct(HttpClient $http, private LoggerInterface $logger) { parent::__construct($http); }

    public function charge(Money $amount, string $token): ChargeResult { /* ... */ }
}

Common pitfalls

  • Deep inheritance trees that are hard to change — favor composition.
  • Traits that depend on undeclared properties of the host class (use abstract methods in the trait to require them).
  • Interfaces with too many methods; keep them small (Interface Segregation).

Key points

  • Depend on interfaces, not implementations
  • Abstract classes share code; interfaces define contracts
  • Use traits sparingly

Further reading: PHP manual: interfaces

Practice questions

When would you choose an abstract class over an interface?

Answer

When implementations share real code or state (e.g., a base HTTP gateway with helper methods). Interfaces are for contracts; you can combine both: an interface for the type, an abstract class as a convenient base.

What problem do traits solve, and what's their main risk?

Answer

They allow reusing methods across unrelated classes without inheritance. Risks: hidden coupling to host class internals, name conflicts, and code that's hard to follow when overused.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?