<?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 => 'en',
  ),
  'this' => 
  array (
    0 => 'language.oop5.inheritance.php',
    1 => 'Object Inheritance',
    2 => 'Object Inheritance',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Classes and Objects',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.visibility.php',
    1 => 'Visibility',
  ),
  'next' => 
  array (
    0 => 'language.oop5.paamayim-nekudotayim.php',
    1 => 'Scope Resolution Operator (::)',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    '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">Object Inheritance</h2>
  <p class="para">
   Inheritance is a well-established programming principle, and PHP makes use
   of this principle in its object model. This principle will affect the way
   many classes and objects relate to one another.
  </p>
  <p class="para">
   For example, when extending a class, the subclass inherits all of the
   public and protected methods, properties and constants from the parent class.
   Unless a class overrides
   those methods, they will retain their original functionality.
  </p>
  <p class="para">
   This is useful for defining and abstracting functionality, and permits the
   implementation of additional functionality in similar objects without the
   need to reimplement all of the shared functionality.
  </p>
  <p class="para">
   Private methods of a parent class are not accessible to a child class. As a result,
   child classes may reimplement a private method themselves without regard for normal
   inheritance rules.  Prior to PHP 8.0.0, however, <code class="literal">final</code> and <code class="literal">static</code>
   restrictions were applied to private methods.  As of PHP 8.0.0, the only private method
   restriction that is enforced is <code class="literal">private final</code> constructors, as that
   is a common way to &quot;disable&quot; the constructor when using static factory methods instead.
  </p>
 <p class="para">
  The <a href="language.oop5.visibility.php" class="link">visibility</a>
  of methods, properties and constants can be relaxed, e.g. a
  <code class="literal">protected</code> method can be marked as
  <code class="literal">public</code>, but they cannot be restricted, e.g.
  marking a <code class="literal">public</code> property as <code class="literal">private</code>.
  An exception are constructors, whose visibility can be restricted, e.g.
  a <code class="literal">public</code> constructor can be marked as <code class="literal">private</code>
  in a child class.
 </p>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    Unless autoloading is used, the classes must be defined before they are
    used. If a class extends another, then the parent class must be declared 
    before the child class structure. This rule applies to classes that inherit 
    other classes and interfaces.
   </p>
  </p></blockquote>
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    It is not allowed to override a read-write property with a <a href="language.oop5.properties.php#language.oop5.properties.readonly-properties" class="link">readonly property</a> or vice versa.
    <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">// Illegal: read-write -&gt; readonly<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>Example #1 Inheritance Example</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 is great.' </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">// Output: '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">// Output: 'PHP is great' <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">// Output: '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">// Output: 'PHP is great'<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">Return Type Compatibility with Internal Classes</h3>
 
   <p class="para">
    Prior to PHP 8.1, most internal classes or methods didn&#039;t declare their return types,
    and any return type was allowed when extending them.
   </p>
 
   <p class="para">
    As of PHP 8.1.0, most internal methods started to &quot;tentatively&quot; declare their return type,
    in that case the return type of methods should be compatible with the parent being extended;
    otherwise, a deprecation notice is emitted.
    Note that lack of an explicit return declaration is also considered a signature mismatch,
    and thus results in the deprecation notice.
   </p>
 
   <p class="para">
    If the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns,
    a <span class="classname"><a href="class.returntypewillchange.php" class="classname">ReturnTypeWillChange</a></span> attribute can be added to silence the deprecation notice.
   </p>
 
   <div class="example" id="example-2">
    <p><strong>Example #2 The overriding method does not declare any return type</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>Example #3 The overriding method declares a wrong return type</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>Example #4 The overriding method declares a wrong return type without a deprecation notice</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">// No notice is triggered <br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
 
  </div>

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