PHP unterstützt abstrakte Klassen und Methoden. Abstrakt definierte Klassen
können nicht instantiiert werden. Jede Klasse, die wenigstens eine abstrakte
Methode oder Eigenschaft enthält, muss ebenso abstrakt sein. Als abstrakt
definierte Methoden deklarieren nur die Signatur der Methode und ob sie
öffenlich oder geschützt ist - sie können nicht die Implementierung
definieren. Als abstrakt definierte Eigenschaften können eine Anforderung
für das Verhalten von get
oder set
deklarieren und eine Implementierung für eine, aber nicht für beide
Operationen bereitstellen.
Wenn von einer abstrakten Klasse abgeleitet wird, müssen alle in der Deklaration der Elternklasse als abstrakt bezeichneten Methoden durch das Kind definiert werden und den üblichen Regeln zur Vererbung und Signatur-Kompatibilität folgen.
Seit PHP 8.4 kann eine abstrakte Klasse eine abstrakte Eigenschaft deklarieren, die entweder öffenlich oder geschützt ist. Eine abstrakte Eigenschaft, die geschützt ist, kann durch eine Eigenschaft erfüllt werden, die entweder vom geschützten oder vom öffenlichen Geltungsbereich aus lesbar/schreibbar ist
Eine abstrakte Eigenschaft kann entweder durch eine Standardeigenschaft oder durch eine Eigenschaft mit definierten Hooks erfüllt werden, die der erforderlichen Operation entspricht.
Beispiel #1 Beispiel für eine abstrakte Methode
<?php
abstract class AbstractClass
{
// Die abgeleitete Klasse zwingen, diese Methoden zu definieren
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Gemeinsame Methode
public function printOut()
{
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue()
{
return "ConcreteClass1";
}
public function prefixValue($prefix)
{
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue()
{
return "ConcreteClass2";
}
public function prefixValue($prefix)
{
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1();
$class1->printOut();
echo $class1->prefixValue('FOO_'), "\n";
$class2 = new ConcreteClass2();
$class2->printOut();
echo $class2->prefixValue('FOO_'), "\n";
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
Beispiel #2 Beispiel für eine abstrakte Methode
<?php
abstract class AbstractClass
{
// Eine abstrakte Methode muss nur die verpflichtenden Parameter definieren
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// Eine Kindklasse kann optionale Parameter definieren, die sich nicht in der
// Signatur der Elternklasse wiederfinden
public function prefixName($name, $separator = ".")
{
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass();
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Mr. Pacman Mrs. Pacwoman
Beispiel #3 Beispiel für eine abstrakte Eigenschaft
<?php
abstract class A
{
// Erweiternde Klassen müssen eine öffentlich lesbare Eigenschaft haben
abstract public string $readable {
get;
}
// Erweiternde Klassen müssen eine geschützt oder öffentlich schreibbare
// Eigenschaft haben
abstract protected string $writeable {
set;
}
// Erweiternde Klassen müssen eine geschützte oder öffentliche symmetrische
// Eigenschaft haben
abstract protected string $both {
get;
set;
}
}
class C extends A
{
// Dies erfüllt die Anforderung und macht sie außerdem einstellbar, was
// gültig ist
public string $readable;
// Dies würde die Anforderung NICHT erfüllen, da sie nicht öffentlich
// lesbar ist
protected string $readable;
// Dies erfüllt die Anforderung genau, ist also ausreichend.
// Es darf nur geschrieben werden, und zwar nur aus dem geschützten Bereich
protected string $writeable {
set => $value;
}
// Dies erweitert die Sichtbarkeit von geschützt auf öffentlich, was in
// Ordnung ist
public string $both;
}
?>
Eine abstrakte Eigenschaft einer abstrakten Klasse kann Implementierungen
für jeden Hook bereitstellen, muss aber entweder get
oder
set
deklariert, aber nicht definiert haben (wie im obigen
Beispiel).
Beispiel #4 Beispiel für eine abstrakte Eigenschaft mit Hooks
<?php
abstract class A
{
// Dies bietet eine vorgegebene (aber überschreibbare) set-Implementierung
// und erfordert, dass Kindklassen eine get-Implementierung bereitstellen
abstract public string $foo {
get;
set {
$this->foo = $value;
}
}
}
?>