<?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.inheritance.php',
    1 => 'Objekt-Vererbung',
    2 => 'Objekt-Vererbung',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Klassen und Objekte',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.visibility.php',
    1 => 'Sichtbarkeit',
  ),
  'next' => 
  array (
    0 => 'language.oop5.paamayim-nekudotayim.php',
    1 => 'G&uuml;ltigkeitsbereichsoperator (::)',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'de',
    'path' => 'language/oop5/inheritance.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.inheritance" class="sect1">
  <h2 class="title">Objekt-Vererbung</h2>
  <p class="para">
   Vererbung ist ein gängiges Prinzip der Programmierung und PHP verwendet
   dieses Prinzip in seinem Objektmodell. Dieses Prinzip beeinflusst die
   Art und Weise, in der mehrere Klassen und Objekte in Beziehung zueinander
   stehen.
  </p>
  <p class="para">
   Wenn zum Beispiel eine Klasse erweitert wird, so erbt die Unterklasse
   alle Methoden der Sichtbarkeiten public und protected sowie alle
   Eigenschaften und Konstanten von der Elternklasse. Wenn eine Klasse diese
   Methoden nicht überschreibt, wird die ursprüngliche Funktionalität
   beibehalten.
  </p>
  <p class="para">
   Dies ist nützlich, um Funktionalität zu definieren und zu abstrahieren und
   erlaubt es, zusätzliche Funktionalität in ähnlichen Objekten zu
   implementieren, ohne sämtliche gemeinsame Funktionalitäten neu
   implementieren zu müssen.
  </p>
  <p class="para">
   Private Methoden einer Elternklasse sind für eine Kindklasse nicht
   zugänglich. Folglich können Kindklassen eine private Methode ohne
   Berücksichtigung der normalen Vererbungsregeln selbst reimplementieren. Vor
   PHP 8.0.0 wurden jedoch die Einschränkungen  <code class="literal">final</code> und
   <code class="literal">static</code> auf private Methoden angewandt. Ab PHP 8.0.0 ist
   die einzige Einschränkung für private Methoden, die erzwungen wird, die die
   <code class="literal">private final</code> bei Konstruktoren, da dies ein üblicher
   Weg ist, den Konstruktor zu &quot;deaktivieren&quot;, wenn stattdessen statische
   Fabrikmethoden (factory methods) verwendet werden.
  </p>
  <p class="para">
   Die <a href="language.oop5.visibility.php" class="link">Sichtbarkeit</a> von
   Methoden, Eigenschaften und Konstanten kann gelockert werden, so kann z. B.
   eine <code class="literal">protected</code> Methode als <code class="literal">public</code>
   markiert werden, aber sie können nicht eingeschränkt werden, indem z. B.
   eine <code class="literal">public</code> Eigenschaft als <code class="literal">private</code>
   markiert wird. Eine Ausnahme sind Konstruktoren, deren Sichtbarkeit
   eingeschränkt werden kann, z. B. kann ein <code class="literal">public</code>
   Konstruktor in einer Kindklasse als <code class="literal">private</code> markiert
   werden.
  </p>

  <blockquote class="note"><p><strong class="note">Hinweis</strong>: 
   <p class="para">
    Wenn Autoloading nicht verwendet wird, so müssen die Klassen definiert werden,
    bevor sie verwendet werden. Wenn eine Klasse eine andere erweitert, so muss die
    Elternklasse vor der Kindklasse deklariert werden. Diese Regel gilt für Klassen,
    die von anderen Klassen und Interfaces erben.
   </p>
  </p></blockquote>
  <blockquote class="note"><p><strong class="note">Hinweis</strong>: 
   <p class="para">
    Es ist nicht erlaubt, eine schreib- und lesbare Eigenschaft mit einer
    <a href="language.oop5.properties.php#language.oop5.properties.readonly-properties" class="link">schreibgeschützten Eigenschaft</a>
    zu überschreiben oder umgekehrt.
    <div class="informalexample">
     <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">class </span><span style="color: #0000BB">A </span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $prop</span><span style="color: #007700">;<br />}<br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A </span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Unzulässig: lesen-schreiben -&gt; nur-lesen<br />    </span><span style="color: #007700">public readonly </span><span style="color: #0000BB">int $prop</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </p></blockquote>

  <div class="example" id="example-1">
   <p><strong>Beispiel #1 Beispiel für Vererbung</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">class </span><span style="color: #0000BB">Foo<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">printItem</span><span style="color: #007700">(</span><span style="color: #0000BB">$string</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #DD0000">'Foo: ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$string </span><span style="color: #007700">. </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">printPHP</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #DD0000">'PHP ist großartig.' </span><span style="color: #007700">. </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Bar </span><span style="color: #007700">extends </span><span style="color: #0000BB">Foo<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">printItem</span><span style="color: #007700">(</span><span style="color: #0000BB">$string</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #DD0000">'Bar: ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$string </span><span style="color: #007700">. </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$foo </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$bar </span><span style="color: #007700">= new </span><span style="color: #0000BB">Bar</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$foo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printItem</span><span style="color: #007700">(</span><span style="color: #DD0000">'baz'</span><span style="color: #007700">); </span><span style="color: #FF8000">// Ausgabe: 'Foo: baz'<br /></span><span style="color: #0000BB">$foo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printPHP</span><span style="color: #007700">();       </span><span style="color: #FF8000">// Ausgabe: 'PHP ist großartig.'<br /></span><span style="color: #0000BB">$bar</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printItem</span><span style="color: #007700">(</span><span style="color: #DD0000">'baz'</span><span style="color: #007700">); </span><span style="color: #FF8000">// Ausgabe: 'Bar: baz'<br /></span><span style="color: #0000BB">$bar</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">printPHP</span><span style="color: #007700">();       </span><span style="color: #FF8000">// Ausgabe: 'PHP ist großartig.'<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>

  <div class="sect2" id="language.oop5.inheritance.internal-classes">
   <h3 class="title">Kompatibilität des Rückgabetyps bei internen Klassen</h3>

   <p class="para">
    Vor PHP 8.1 haben die meisten internen Klassen oder Methoden ihren
    Rückgabetyp nicht deklariert und wenn sie erweitert wurden, war jeder
    Rückgabetyp erlaubt.
   </p>

   <p class="para">
    Seit PHP 8.1.0 sind die meisten internen Methoden dazu übergegangen, den
    Typ des Rückgabewertes &quot;vorläufig&quot; zu deklarieren. In diesem Fall muss der
    Typ des Rückgabewerts einer Methode mit dem des erweiterten Elternteils
    kompatibel sein, andernfalls wird ein Missbilligungs-Hinweis ausgegeben.
    Es ist zu beachten, dass eine fehlende explizite Deklaration des
    Rückgabetyps ebenfalls als Signaturfehler betrachtet wird, und daher zu
    einer entsprechenden Meldung führt.
   </p>

   <p class="para">
    Wenn der Rückgabetyp für eine überschreibende Methode aufgrund von
    Kompatibilitätsproblemen zwischen PHP-Versionen nicht deklariert werden
    kann, kann das Attribut <span class="classname"><a href="class.returntypewillchange.php" class="classname">ReturnTypeWillChange</a></span>
    hinzugefügt werden, um den Missbilligungs-Hinweis zu unterdrücken.
   </p>

   <div class="example" id="example-2">
    <p><strong>Beispiel #2 Die überschreibende Methode deklariert keinen Rückgabetyp</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyDateTime </span><span style="color: #007700">extends </span><span style="color: #0000BB">DateTime<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">modify</span><span style="color: #007700">(</span><span style="color: #0000BB">string $modifier</span><span style="color: #007700">) { return </span><span style="color: #0000BB">false</span><span style="color: #007700">; }<br />}<br /><br /></span><span style="color: #FF8000">// "Deprecated: Return type of MyDateTime::modify(string $modifier) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>

   <div class="example" id="example-3">
    <p><strong>Beispiel #3 Die überschreibende Methode deklariert einen falschen Rückgabetyp</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyDateTime </span><span style="color: #007700">extends </span><span style="color: #0000BB">DateTime<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">modify</span><span style="color: #007700">(</span><span style="color: #0000BB">string $modifier</span><span style="color: #007700">): ?</span><span style="color: #0000BB">DateTime </span><span style="color: #007700">{ return </span><span style="color: #0000BB">null</span><span style="color: #007700">; }<br />}<br /><br /></span><span style="color: #FF8000">// "Deprecated: Return type of MyDateTime::modify(string $modifier): ?DateTime should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice" as of PHP 8.1.0<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>

   <div class="example" id="example-4">
    <p><strong>Beispiel #4 Die überschreibende Methode deklariert einen falschen Rückgabetyp ohne Missbilligungs-Hinweis</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyDateTime </span><span style="color: #007700">extends </span><span style="color: #0000BB">DateTime<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">/**<br />     * @return DateTime|false<br />     */<br />    </span><span style="color: #007700">#[</span><span style="color: #0000BB">\ReturnTypeWillChange</span><span style="color: #007700">]<br />    public function </span><span style="color: #0000BB">modify</span><span style="color: #007700">(</span><span style="color: #0000BB">string $modifier</span><span style="color: #007700">) { return </span><span style="color: #0000BB">false</span><span style="color: #007700">; }<br />}<br /><br /></span><span style="color: #FF8000">// Es wird kein Missbilligungs-Hinweis ausgelöst<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>

  </div>

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