<?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 => 'es',
  ),
  'this' => 
  array (
    0 => 'language.oop5.inheritance.php',
    1 => 'Herencia',
    2 => 'Herencia',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Clases y objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.visibility.php',
    1 => 'Visibilidad',
  ),
  'next' => 
  array (
    0 => 'language.oop5.paamayim-nekudotayim.php',
    1 => 'El operador de resoluci&oacute;n de &aacute;mbito (::)',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    '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">Herencia</h2>
 <p class="para">
  La herencia es uno de los grandes principios de la programación orientada a objetos (POO), y
  PHP la implementa en su modelo de objetos. Este principio afectará la manera en que
  muchas clases están relacionadas entre sí.
 </p>
 <p class="para">
  Por ejemplo, cuando una clase es extendida, la clase hija hereda todas
  las métodos públicos y protegidos, propiedades y constantes de la clase padre. Mientras una clase no sobrescriba
  estos métodos, conservan su funcionalidad original.
 </p>
 <p class="para">
  La herencia es muy útil para definir y abstraer ciertas funcionalidades
  comunes a varias clases, permitiendo al mismo tiempo la implementación de
  funcionalidades adicionales en las clases hijas, sin tener que reimplementar
  en su interior todas las funcionalidades comunes.
 </p>
 <p class="para">
  Los métodos privados de una clase padre no son accesibles para la clase hija.
  Por consiguiente, las clases hijas pueden reimplementar un método privado por sí mismas
  sin preocuparse por las reglas normales de herencia.
  Anterior a PHP 8.0.0, sin embargo, las restricciones <code class="literal">final</code>
  y <code class="literal">static</code> se aplicaban a los métodos privados.
  A partir de PHP 8.0.0, la única restricción de método privado que se impone
  es <code class="literal">private final</code> en los constructores, ya que es una
  manera común para &quot;desactivar&quot; el constructor cuando se utilizan métodos de fábrica estáticos en su lugar.
 </p>
 <p class="para">
  La <a href="language.oop5.visibility.php" class="link">visibilidad</a>
  de los métodos, propiedades y constantes puede ser relajada, es decir, un
  método <code class="literal">protected</code> puede ser marcado como
  <code class="literal">public</code>, pero no pueden ser restringidos, por ejemplo,
  marcar una propiedad <code class="literal">public</code> como <code class="literal">private</code>.
  Una excepción son los constructores, para los cuales la visibilidad puede ser restringida,
  por ejemplo, un constructor <code class="literal">public</code> puede ser anotado
  como <code class="literal">private</code> en la clase hija.
 </p>

 <blockquote class="note"><p><strong class="note">Nota</strong>: 
  <p class="para">
   A menos que se utilice la autocarga, las clases deben ser conocidas antes de ser
   utilizadas. Las clases padres deben ser definidas antes de escribir una herencia. Esta
   regla general se aplica también en el caso de herencia o implementación de interfaces.
  </p>
 </p></blockquote>

 <blockquote class="note"><p><strong class="note">Nota</strong>: 
  <p class="para">
   No está permitido redefinir una propiedad de lectura-escritura con una
   <a href="language.oop5.properties.php#language.oop5.properties.readonly-properties" class="link">propiedad de solo lectura</a> o viceversa.
   <div class="informalexample">
    <div class="example-contents">
<div class="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">// Ilegal: 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>Ejemplo #1 Ejemplo de herencia</strong></p>
   <div class="example-contents">
<div class="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 es genial' </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">// Muestra: '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">// Muestra: 'PHP es genial'<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">// Muestra: '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">// Muestra: 'PHP es genial'<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">Compatibilidad de los tipos de retorno con las clases internas</h3>

  <p class="para">
   Anterior a PHP 8.1, la mayoría de las clases o métodos internos no declaraban su
   tipo de retorno, y cualquier tipo de retorno estaba permitido al heredarlos.
  </p>

  <p class="para">
   A partir de PHP 8.1.0, la mayoría de los métodos internos comenzaron a declarar &quot;provisionalmente&quot;
   su tipo de retorno, en este caso, el tipo de retorno de los métodos debe ser compatible con la clase
   padre; en caso contrario, se emite una notificación de deprecación.
   Tenga en cuenta que la ausencia de una declaración de retorno explícita también se considera un error de firma, y por lo tanto provoca el aviso de deprecación.
  </p>

  <p class="para">
   Si el tipo de retorno no puede ser declarado para un método de sobrecarga debido a problemas de
   compatibilidad entre versiones de PHP, un atributo <span class="classname"><a href="class.returntypewillchange.php" class="classname">ReturnTypeWillChange</a></span> puede ser
   añadido para silenciar el aviso de deprecación.
  </p>

  <div class="example" id="example-2">
   <p><strong>Ejemplo #2 El método sobrecargado no declara tipo de retorno.</strong></p>
   <div class="example-contents">
<div class="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">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" A partir de PHP 8.1.0</span></span></code></div>
   </div>

  </div>

  <div class="example" id="example-3">
   <p><strong>Ejemplo #3 El método sobrecargado declara un tipo de retorno incorrecto.</strong></p>
   <div class="example-contents">
<div class="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">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" A partir de PHP 8.1.0</span></span></code></div>
   </div>

  </div>

  <div class="example" id="example-4">
   <p><strong>Ejemplo #4 El método sobrecargado declara un tipo de retorno incorrecto sin aviso de deprecación.</strong></p>
   <div class="example-contents">
<div class="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">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 se emite ningún aviso</span></span></code></div>
   </div>

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