<?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 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'language.oop5.inheritance.php',
    1 => 'Heran&ccedil;a de Objetos',
    2 => 'Heran&ccedil;a de Objetos',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Classes e Objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.visibility.php',
    1 => 'Visibilidade',
  ),
  'next' => 
  array (
    0 => 'language.oop5.paamayim-nekudotayim.php',
    1 => 'Operador de Resolu&ccedil;&atilde;o de Escopo (::)',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    '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">Herança de Objetos</h2>
  <p class="para">
   Herança é um conceito de programação estabelecido, e o PHP faz
   uso deste em seu modelo de objetos. Este princípio afeta a forma
   com que classes e objetos se relacionam com outras.
  </p>
  <p class="para">
   Por exemplo, ao estender uma classe, a subclasse herda todos os métodos
   públicos e protegidos, propriedades e constantes da classe pai.
   A não que uma classe sobrescreva
   estes métodos, eles manterão sua funcionalidade original.
  </p>
  <p class="para">
   Isto é útil para definir uma funcionalidade abstrata, e permitir a
   implementação de uma funcionalidade adicional em objetos similares sem a
   necessidade de reimplementar todas as funcionalidades compartilhadas.
  </p>
  <p class="para">
   Os métodos privados de uma classe pai não são acessíveis a uma classe filha. Como resultado,
   as classes filhas podem reimplementar um método privado sem levar em conta as regras normais
   de herança. Antes do PHP 8.0.0, entretanto, as restrições <code class="literal">final</code> e <code class="literal">static</code>
   eram aplicadas aos métodos privados. Desde o PHP 8.0.0, a única restrição de método privado
   que é aplicada é <code class="literal">private final</code> para construtores, já que essa
   é uma maneira comum de &quot;desabilitar&quot; o construtor ao usar métodos de fábrica estáticos.
  </p>
 <p class="para">
  A <a href="language.oop5.visibility.php" class="link">visibilidade</a>
  de métodos, propriedades e constantes pode ser relaxada, por exemplo, um
  método com <code class="literal">protected</code> pode ser marcado como
  <code class="literal">public</code>, mas não pode ser restrito, por exemplo,
  marcar uma propriedade que tenha <code class="literal">public</code> como <code class="literal">private</code>.
  Uma exceção são os construtores, cuja visibilidade pode ser restrita, ou seja,
  um construtor <code class="literal">public</code> pode ser declarado como <code class="literal">private</code>
  numa classe filha.
 </p>

  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    A não ser que o autoload seja usado, as classes devem ser definidas antes de
    utilizadas. Se uma classe estende outra, a classe pai deve ser declarada
    antes da estrutura da classe filha. Esta regra se aplica a classes que herdam
    outras classes e interfaces.
   </p>
  </p></blockquote>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    Não é permitido sobrescrever uma propriedade de leitura/gravação com um <a href="language.oop5.properties.php#language.oop5.properties.readonly-properties" class="link">propriedade somente de leitura</a> ou 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>Exemplo #1 Exemplo de Herança</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 é ótimo' </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">// Saída: '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">// Saída: 'PHP é ótimo'<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">// Saída: '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">// Saída: 'PHP é ótimo'<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">Compatibilidade de Tipo de Retorno com Classes Internas</h3>

   <p class="para">
    Antes do PHP 8.1, a maioria das classes ou métodos internos não declaravam seus tipos de retorno,
    e qualquer tipo de retorno era permitido ao estendê-los.
   </p>

   <p class="para">
    A partir do PHP 8.1.0, a maioria dos métodos internos começaram a declarar seu tipo de retorno de forma &quot;experimental&quot;,
    nesse caso o tipo de retorno dos métodos deve ser compatível com o pai sendo estendido,
    do contrário, um aviso de descontinuação é emitido.
    Note que a ausência de uma declaração de retorno explícita também é considerada uma incompatibilidade de assinatura
    e, portanto, resulta no aviso de descontinuação.
   </p>

   <p class="para">
    Se o tipo de retorno não puder ser declarado para um método que sobrepõe devido à preocupações com compatibilidade entre versões PHP,
    um atributo <span class="classname"><a href="class.returntypewillchange.php" class="classname">ReturnTypeWillChange</a></span> pode ser adicionado para silenciar o aviso de descontinuação.
   </p>

   <div class="example" id="example-2">
    <p><strong>Exemplo #2 O método que sobrepõe não declara nenhum tipo de retorno</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">MeuDateTime </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 MeuDateTime::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 do 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>Exemplo #3 O método que sobrepõe declara um tipo de retorno errado</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">MeuDateTime </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 MeuDateTime::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 do 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>Exemplo #4 O método que sobrepõe declara um tipo de retorno errado sem um aviso de descontinuação</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">MeuDateTime </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">// Nenhum aviso é emitido<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>

  </div>

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