Interface oder eine abstrakte Klasse: Welche soll verwendet werden?

Ein Interface legt eine Reihe von Methoden fest, die eine Klasse implementieren muss, gibt jedoch keine Implementierung für diese Methoden an. Eine abstrakte Klasse kann hingegen einige Implementierungen für ihre Methoden bereitstellen, zusätzlich zur Definition von Methoden, die abgeleitete Klassen implementieren müssen.

Im Allgemeinen sollten Sie ein Interface verwenden, wenn Sie einen Vertrag für eine Klasse festlegen möchten, aber keine Implementierung bereitstellen möchten. Verwenden Sie eine abstrakte Klasse, wenn Sie eine gemeinsame Implementierung für einige Methoden bereitstellen möchten, aber trotzdem ermöglichen möchten, dass abgeleitete Klassen ihr eigenes einzigartiges Verhalten hinzufügen.

In PHP, können sowohl abstrakte Klasse als auch Interface Konstanten, Eigenschaften und Methoden haben, aber eine abstrakte Klasse kann einen Konstruktor haben und ein Interface nicht.

Hier ist ein Beispiel:

<?php

interface Shape
{
  public function getArea(): float;
}

abstract class AbstractShape implements Shape
{
  protected float $width;
  protected float $height;

  public function __construct(float $width, float $height)
  {
    $this->width = $width;
    $this->height = $height;
  }

  abstract public function getArea(): float;
}

class Rectangle extends AbstractShape
{
  public function __construct(float $width, float $height)
  {
    parent::__construct($width, $height);
  }

  public function getArea(): float
  {
    return $this->width * $this->height;
  }
}

class Triangle extends AbstractShape
{
  public function __construct(float $width, float $height)
  {
    parent::__construct($width, $height);
  }

  public function getArea(): float
  {
    return 0.5 * $this->width * $this->height;
  }
}

$rectangle = new Rectangle(5, 10);
$triangle = new Triangle(5, 10);

echo "The area of the rectangle is: " . $rectangle->getArea() . "\n";
echo "The area of the triangle is: " . $triangle->getArea() . "\n";

In diesem Beispiel definiert die Schnittstelle Shape einen Vertrag für Klassen, die Formen darstellen, mit einer einzigen Methode getArea(), die die Fläche der Form zurückgibt. Die Klasse AbstractShape bietet eine allgemeine Implementierung für die Breite und Höhe einer Form sowie eine Standardimplementierung von getArea(), die eine abstrakte Methode aufruft. Die Klassen Rectangle und Triangle erweitern beide die Klasse AbstractShape und bieten ihre eigene Implementierung von getArea().