<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.oop5.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'de',
  ),
  'this' => 
  array (
    0 => 'language.oop5.abstract.php',
    1 => 'Klassenabstraktion',
    2 => 'Klassenabstraktion',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Klassen und Objekte',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.static.php',
    1 => 'Schl&uuml;sselwort static',
  ),
  'next' => 
  array (
    0 => 'language.oop5.interfaces.php',
    1 => 'Objekt-Interfaces (Schnittstellen)',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'de',
    'path' => 'language/oop5/abstract.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.abstract" class="sect1">
  <h2 class="title">Klassenabstraktion</h2>

  <p class="para">
   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 <code class="literal">get</code> oder <code class="literal">set</code>
   deklarieren und eine Implementierung für eine, aber nicht für beide
   Operationen bereitstellen.
  </p>

  <p class="para">
   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
   <a href="language.oop5.inheritance.php" class="link">Vererbung</a> und
   <a href="language.oop5.basic.php#language.oop.lsp" class="link">Signatur-Kompatibilität</a> folgen.
  </p>

  <p class="simpara">
   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
  </p>
  <p class="simpara">
   Eine abstrakte Eigenschaft kann entweder durch eine Standardeigenschaft oder
   durch eine Eigenschaft mit definierten
   <a href="language.oop5.property-hooks.php" class="link">Hooks</a> erfüllt werden,
   die der erforderlichen Operation entspricht.
  </p>

  <div class="example" id="example-1">
   <p><strong>Beispiel #1 Beispiel für eine abstrakte Methode</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Die abgeleitete Klasse zwingen, diese Methoden zu definieren<br />    </span><span style="color: #007700">abstract protected function </span><span style="color: #0000BB">getValue</span><span style="color: #007700">();<br />    abstract protected function </span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">);<br /><br />    </span><span style="color: #FF8000">// Gemeinsame Methode<br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">printOut</span><span style="color: #007700">()<br />    {<br />        print </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getValue</span><span style="color: #007700">() . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">ConcreteClass1 </span><span style="color: #007700">extends </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br />    protected function </span><span style="color: #0000BB">getValue</span><span style="color: #007700">()<br />    {<br />        return </span><span style="color: #DD0000">"ConcreteClass1"</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">)<br />    {<br />        return </span><span style="color: #DD0000">"</span><span style="color: #007700">{</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">}</span><span style="color: #DD0000">ConcreteClass1"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">ConcreteClass2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">getValue</span><span style="color: #007700">()<br />    {<br />        return </span><span style="color: #DD0000">"ConcreteClass2"</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">)<br />    {<br />        return </span><span style="color: #DD0000">"</span><span style="color: #007700">{</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">}</span><span style="color: #DD0000">ConcreteClass2"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$class1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConcreteClass1</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$class1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printOut</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$class1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #DD0000">'FOO_'</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$class2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConcreteClass2</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$class2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printOut</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$class2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixValue</span><span style="color: #007700">(</span><span style="color: #DD0000">'FOO_'</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>Das oben gezeigte Beispiel erzeugt folgende Ausgabe:</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
</pre></div>
   </div>
  </div>

  <div class="example" id="example-2">
   <p><strong>Beispiel #2 Beispiel für eine abstrakte Methode</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Eine abstrakte Methode muss nur die verpflichtenden Parameter definieren<br />    </span><span style="color: #007700">abstract protected function </span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br />}<br /><br />class </span><span style="color: #0000BB">ConcreteClass </span><span style="color: #007700">extends </span><span style="color: #0000BB">AbstractClass<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Eine Kindklasse kann optionale Parameter definieren, die sich nicht in der<br />    // Signatur der Elternklasse wiederfinden<br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$separator </span><span style="color: #007700">= </span><span style="color: #DD0000">"."</span><span style="color: #007700">)<br />    {<br />        if (</span><span style="color: #0000BB">$name </span><span style="color: #007700">== </span><span style="color: #DD0000">"Pacman"</span><span style="color: #007700">) {<br />            </span><span style="color: #0000BB">$prefix </span><span style="color: #007700">= </span><span style="color: #DD0000">"Mr"</span><span style="color: #007700">;<br />        } elseif (</span><span style="color: #0000BB">$name </span><span style="color: #007700">== </span><span style="color: #DD0000">"Pacwoman"</span><span style="color: #007700">) {<br />            </span><span style="color: #0000BB">$prefix </span><span style="color: #007700">= </span><span style="color: #DD0000">"Mrs"</span><span style="color: #007700">;<br />        } else {<br />            </span><span style="color: #0000BB">$prefix </span><span style="color: #007700">= </span><span style="color: #DD0000">""</span><span style="color: #007700">;<br />        }<br /><br />        return </span><span style="color: #DD0000">"</span><span style="color: #007700">{</span><span style="color: #0000BB">$prefix</span><span style="color: #007700">}{</span><span style="color: #0000BB">$separator</span><span style="color: #007700">}</span><span style="color: #DD0000"> </span><span style="color: #007700">{</span><span style="color: #0000BB">$name</span><span style="color: #007700">}</span><span style="color: #DD0000">"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$class </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConcreteClass</span><span style="color: #007700">();<br />echo </span><span style="color: #0000BB">$class</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #DD0000">"Pacman"</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$class</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefixName</span><span style="color: #007700">(</span><span style="color: #DD0000">"Pacwoman"</span><span style="color: #007700">), </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>Das oben gezeigte Beispiel erzeugt folgende Ausgabe:</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Mr. Pacman
Mrs. Pacwoman
</pre></div>
   </div>
  </div>
  <div class="example" id="example-3">
   <p><strong>Beispiel #3 Beispiel für eine abstrakte Eigenschaft</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Erweiternde Klassen müssen eine öffentlich lesbare Eigenschaft haben<br />    </span><span style="color: #007700">abstract public </span><span style="color: #0000BB">string $readable </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get</span><span style="color: #007700">;<br />    }<br /><br />    </span><span style="color: #FF8000">// Erweiternde Klassen müssen eine geschützt oder öffentlich schreibbare<br />    // Eigenschaft haben<br />    </span><span style="color: #007700">abstract protected </span><span style="color: #0000BB">string $writeable </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set</span><span style="color: #007700">;<br />    }<br /><br />    </span><span style="color: #FF8000">// Erweiternde Klassen müssen eine geschützte oder öffentliche symmetrische<br />    // Eigenschaft haben<br />    </span><span style="color: #007700">abstract protected </span><span style="color: #0000BB">string $both </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">set</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">C </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Dies erfüllt die Anforderung und macht sie außerdem einstellbar, was<br />    // gültig ist<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">string $readable</span><span style="color: #007700">;<br /><br />    </span><span style="color: #FF8000">// Dies würde die Anforderung NICHT erfüllen, da sie nicht öffentlich<br />    // lesbar ist<br />    </span><span style="color: #007700">protected </span><span style="color: #0000BB">string $readable</span><span style="color: #007700">;<br /><br />    </span><span style="color: #FF8000">// Dies erfüllt die Anforderung genau, ist also ausreichend.<br />    // Es darf nur geschrieben werden, und zwar nur aus dem geschützten Bereich<br />    </span><span style="color: #007700">protected </span><span style="color: #0000BB">string $writeable </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />    }<br /><br />    </span><span style="color: #FF8000">// Dies erweitert die Sichtbarkeit von geschützt auf öffentlich, was in<br />    // Ordnung ist<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">string $both</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Eine abstrakte Eigenschaft einer abstrakten Klasse kann Implementierungen
   für jeden Hook bereitstellen, muss aber entweder <code class="literal">get</code> oder
   <code class="literal">set</code> deklariert, aber nicht definiert haben (wie im obigen
   Beispiel).
  </p>
  <div class="example" id="example-4">
   <p><strong>Beispiel #4 Beispiel für eine abstrakte Eigenschaft mit Hooks</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Dies bietet eine vorgegebene (aber überschreibbare) set-Implementierung<br />    // und erfordert, dass Kindklassen eine get-Implementierung bereitstellen<br />    </span><span style="color: #007700">abstract public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get</span><span style="color: #007700">;<br /><br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">{<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div><?php manual_footer($setup); ?>