<?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.traits.php',
    1 => 'Traits',
    2 => 'Traits',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Clases y objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.interfaces.php',
    1 => 'Interfaces',
  ),
  'next' => 
  array (
    0 => 'language.oop5.anonymous.php',
    1 => 'Clases an&oacute;nimas',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    'path' => 'language/oop5/traits.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.traits" class="sect1">
 <h2 class="title">Traits</h2>
 <p class="para">
  PHP implementa una manera de reutilizar código llamada Traits.
 </p>
 <p class="para">
  Los traits son un mecanismo de reutilización de código en un lenguaje de herencia simple
  como PHP. Un trait intenta reducir ciertas limitaciones de la herencia simple, permitiendo
  al desarrollador reutilizar un cierto número de métodos en clases independientes. La sémantica entre las clases y los traits reduce la complejidad y evita los problemas
  típicos de la herencia múltiple y los Mixins.
 </p>
 <p class="para">
  Un trait es similar a una clase, pero solo sirve para agrupar funcionalidades de una
  manera interesante. No es posible instanciar un Trait en sí mismo. Es un
  añadido a la herencia tradicional, que permite la composición horizontal de comportamientos,
  es decir, el uso de métodos de clase sin necesidad de herencia.
 </p>

 <div class="example" id="language.oop5.traits.basicexample">
  <p><strong>Ejemplo #1 Ejemplo de uso de Trait</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">trait </span><span style="color: #0000BB">TraitA </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello'</span><span style="color: #007700">;<br />    }<br />}<br /><br />trait </span><span style="color: #0000BB">TraitB </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayWorld</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'World'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">MyHelloWorld<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">TraitA</span><span style="color: #007700">, </span><span style="color: #0000BB">TraitB</span><span style="color: #007700">; </span><span style="color: #FF8000">// Una clase puede usar múltiples traits<br /><br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">sayHelloWorld</span><span style="color: #007700">() {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayHello</span><span style="color: #007700">();<br />        echo </span><span style="color: #DD0000">' '</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayWorld</span><span style="color: #007700">();<br />        echo </span><span style="color: #DD0000">"!\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$myHelloWorld </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyHelloWorld</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$myHelloWorld</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayHelloWorld</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>

  <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
  <div class="example-contents screen">
<div class="cdata"><pre>
Hello World!
</pre></div>
  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.precedence">
  <h3 class="title">Precedencia</h3>
  <p class="para">
   Un método heredado desde una clase madre es sobrescrito por un método proveniente de un Trait.
   El orden de precedencia hace que los métodos de la clase actual
   sobrescriban los métodos provenientes de un Trait, ellos mismos sobrecargando los métodos heredados.
  </p>
  <div class="example" id="language.oop5.traits.precedence.examples.ex1">
   <p><strong>Ejemplo #2 Ejemplo con el orden de precedencia</strong></p>
   <div class="example-contents"><p>
    Un método heredado desde la clase base es sobrescrito por el que proviene
    del Trait. No es el caso de los métodos reales, escritos en la clase base.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Base </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello '</span><span style="color: #007700">;<br />    }<br />}<br /><br />trait </span><span style="color: #0000BB">SayWorld </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">sayHello</span><span style="color: #007700">();<br />        echo </span><span style="color: #DD0000">'World!'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">MyHelloWorld </span><span style="color: #007700">extends </span><span style="color: #0000BB">Base </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">SayWorld</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$o </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyHelloWorld</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayHello</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
   <div class="example-contents screen">
<div class="cdata"><pre>
Hello World!
</pre></div>
   </div>
  </div>
  <div class="example" id="language.oop5.traits.precedence.examples.ex2">
   <p><strong>Ejemplo #3 Otro ejemplo de orden de precedencia</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">HelloWorld </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello World!'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">TheWorldIsNotEnough </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">HelloWorld</span><span style="color: #007700">;<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello Universe!'</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$o </span><span style="color: #007700">= new </span><span style="color: #0000BB">TheWorldIsNotEnough</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayHello</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
   <div class="example-contents screen">
<div class="cdata"><pre>
Hello Universe!
</pre></div>
   </div>
  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.multiple">
  <h3 class="title">Múltiples Traits</h3>
  <p class="para">
   Una clase puede usar múltiples Traits declarándolos con la
   palabra clave <code class="literal">use</code>, separados por comas.
  </p>
  <div class="example" id="language.oop5.traits.multiple.ex1">
   <p><strong>Ejemplo #4 Uso de varios Traits</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">Hello </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello '</span><span style="color: #007700">;<br />    }<br />}<br /><br />trait </span><span style="color: #0000BB">World </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayWorld</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'World'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">MyHelloWorld </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">Hello</span><span style="color: #007700">, </span><span style="color: #0000BB">World</span><span style="color: #007700">;<br />    public function </span><span style="color: #0000BB">sayExclamationMark</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'!'</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$o </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyHelloWorld</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayHello</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayWorld</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayExclamationMark</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
   <div class="example-contents screen">
<div class="cdata"><pre>
Hello World!
</pre></div>
   </div>
  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.conflict">
  <h3 class="title">Resolución de conflictos</h3>
  <p class="para">
   Si dos Traits insertan un método con el mismo nombre, se produce un error fatal si el conflicto no es
   explícitamente resuelto.
  </p>
  <p class="para">
   Para resolver un conflicto de nombres entre Traits usados en la misma clase, se debe usar el operador
   <code class="literal">insteadof</code> para elegir uno de los métodos en conflicto.
  </p>
  <p class="para">
   Dado que este principio solo permite excluir métodos,
   el operador <code class="literal">as</code> puede ser usado para permitir
   la inclusión de uno de los métodos conflictivos bajo otro nombre. Se debe tener en cuenta que
   el operador <code class="literal">as</code> no renombra el método y no afecta
   a otros métodos tampoco.
  </p>
  <div class="example" id="language.oop5.traits.conflict.ex1">
   <p><strong>Ejemplo #5 Resolución de conflictos</strong></p>
   <div class="example-contents"><p>
    En este ejemplo, la clase Talker usa los traits A y B.
    Como A y B tienen métodos conflictivos, se indica que se desea usar
    la variante de smallTalk desde el trait B, y la variante de bigTalk desde el
    trait A.
   </p></div>
   <div class="example-contents"><p>
    La clase Aliased_Talker usa el operador <code class="literal">as</code>
    para poder usar la implementación bigTalk de B bajo un alias
    adicional <code class="literal">talk</code>.
   </p></div>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">A </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">smallTalk</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'a'</span><span style="color: #007700">;<br />    }<br />    public function </span><span style="color: #0000BB">bigTalk</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'A'</span><span style="color: #007700">;<br />    }<br />}<br /><br />trait </span><span style="color: #0000BB">B </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">smallTalk</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'b'</span><span style="color: #007700">;<br />    }<br />    public function </span><span style="color: #0000BB">bigTalk</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'B'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Talker </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">A</span><span style="color: #007700">, </span><span style="color: #0000BB">B </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">smallTalk </span><span style="color: #007700">insteadof </span><span style="color: #0000BB">A</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">bigTalk </span><span style="color: #007700">insteadof </span><span style="color: #0000BB">B</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Aliased_Talker </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">A</span><span style="color: #007700">, </span><span style="color: #0000BB">B </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">smallTalk </span><span style="color: #007700">insteadof </span><span style="color: #0000BB">A</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">bigTalk </span><span style="color: #007700">insteadof </span><span style="color: #0000BB">B</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">bigTalk </span><span style="color: #007700">as </span><span style="color: #0000BB">talk</span><span style="color: #007700">;<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.visibility">
  <h3 class="title">Cambiar la visibilidad de los métodos</h3>
  <p class="para">
   Usando la sintaxis <code class="literal">as</code>, también se puede ajustar
   la visibilidad del método en la clase que lo usa.
  </p>
  <div class="example" id="language.oop5.traits.visibility.ex1">
   <p><strong>Ejemplo #6 Cambiar la visibilidad de los métodos</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">HelloWorld </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello World!'</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #FF8000">// Modificación de la visibilidad del método sayHello<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass1 </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">HelloWorld </span><span style="color: #007700">{ </span><span style="color: #0000BB">sayHello </span><span style="color: #007700">as protected; }<br />}<br /><br /></span><span style="color: #FF8000">// Uso de un alias al modificar la visibilidad<br />// La visibilidad del método sayHello no es modificada<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass2 </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">HelloWorld </span><span style="color: #007700">{ </span><span style="color: #0000BB">sayHello </span><span style="color: #007700">as private </span><span style="color: #0000BB">myPrivateHello</span><span style="color: #007700">; }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.composition">
  <h3 class="title">Traits Compuestos desde otros Traits</h3>
  <p class="para">
   Al igual que las clases pueden usar traits, otros traits también pueden hacerlo. Un trait puede, por lo tanto, usar otros traits y heredar
   todo o parte de ellos.
  </p>
  <div class="example" id="language.oop5.traits.composition.ex1">
   <p><strong>Ejemplo #7 Traits Compuestos desde otros Traits</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">Hello </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHello</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello '</span><span style="color: #007700">;<br />    }<br />}<br /><br />trait </span><span style="color: #0000BB">World </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayWorld</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'World!'</span><span style="color: #007700">;<br />    }<br />}<br /><br />trait </span><span style="color: #0000BB">HelloWorld </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">Hello</span><span style="color: #007700">, </span><span style="color: #0000BB">World</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">MyHelloWorld </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">HelloWorld</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$o </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyHelloWorld</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayHello</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sayWorld</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
   <div class="example-contents screen">
<div class="cdata"><pre>
Hello World!
</pre></div>
   </div>
  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.abstract">
  <h3 class="title">Métodos abstractos en los Traits</h3>
  <p class="para">
   Los traits soportan el uso de métodos abstractos para imponer
   restricciones a las clases subyacentes. Se soportan los métodos públicos, protegidos,
   y privados.
   Anterior a PHP 8.0.0, solo se soportaban los métodos públicos y protegidos abstractos.
  </p>
  <div class="caution"><strong class="caution">Precaución</strong>
    <p class="simpara">
     A partir de PHP 8.0.0, la firma de un método concreto debe seguir las
     <a href="language.oop5.basic.php#language.oop.lsp" class="link">reglas de compatibilidad de firmas</a>.
     Anteriormente, su firma podía ser diferente.
    </p>
   </div>
  <div class="example" id="language.oop5.traits.abstract.ex1">
   <p><strong>Ejemplo #8 Obligaciones requeridas por los métodos abstractos</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">Hello </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">sayHelloWorld</span><span style="color: #007700">() {<br />        echo </span><span style="color: #DD0000">'Hello'</span><span style="color: #007700">.</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getWorld</span><span style="color: #007700">();<br />    }<br />    abstract public function </span><span style="color: #0000BB">getWorld</span><span style="color: #007700">();<br />}<br /><br />class </span><span style="color: #0000BB">MyHelloWorld </span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$world</span><span style="color: #007700">;<br />    use </span><span style="color: #0000BB">Hello</span><span style="color: #007700">;<br />    public function </span><span style="color: #0000BB">getWorld</span><span style="color: #007700">() {<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">world</span><span style="color: #007700">;<br />    }<br />    public function </span><span style="color: #0000BB">setWorld</span><span style="color: #007700">(</span><span style="color: #0000BB">$val</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">world </span><span style="color: #007700">= </span><span style="color: #0000BB">$val</span><span style="color: #007700">;<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div>

 <div class="sect2" id="language.oop5.traits.static">
  <h3 class="title">Atributos estáticos en los Traits</h3>
  <p class="para">
   Los traits pueden definir variables estáticas, métodos estáticos
   y propiedades estáticas.
  </p>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    A partir de PHP 8.1.0, llamar a un método estático o acceder a una
    propiedad estática directamente en un trait es obsoleto.
    Los métodos y propiedades estáticas deberían ser accedidos solo en una clase que use el trait.
   </p>
  </p></blockquote>
  <div class="example" id="language.oop5.traits.static.ex1">
   <p><strong>Ejemplo #9 Variables estáticas</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">trait </span><span style="color: #0000BB">Counter<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">inc</span><span style="color: #007700">()<br />    {<br />        static </span><span style="color: #0000BB">$c </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$c </span><span style="color: #007700">= </span><span style="color: #0000BB">$c </span><span style="color: #007700">+ </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />        echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$c</span><span style="color: #DD0000">\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">C1<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">Counter</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">C2<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">Counter</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$o </span><span style="color: #007700">= new </span><span style="color: #0000BB">C1</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$o</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">inc</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$p </span><span style="color: #007700">= new </span><span style="color: #0000BB">C2</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$p</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">inc</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
1
1
</pre></div>
    </div>
  </div>
  <div class="example" id="language.oop5.traits.static.ex2">
   <p><strong>Ejemplo #10 Métodos estáticos</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">trait </span><span style="color: #0000BB">StaticExample<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">doSomething</span><span style="color: #007700">()<br />    {<br />        return </span><span style="color: #DD0000">'Doing something'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">StaticExample</span><span style="color: #007700">;<br />}<br /><br />echo </span><span style="color: #0000BB">Example</span><span style="color: #007700">::</span><span style="color: #0000BB">doSomething</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
Doing something
</pre></div>
    </div>
  </div>
  <div class="example" id="language.oop5.traits.static.ex3">
   <p><strong>Ejemplo #11 Propiedades estáticas</strong></p>
   <div class="caution"><strong class="caution">Precaución</strong>
     <p class="simpara">
      Antes de PHP 8.3.0, las propiedades estáticas definidas en un trait eran compartidas
      entre todas las clases de la misma jerarquía de herencia que usaban ese trait.
      A partir de PHP 8.3.0, si una clase hija usa un trait con una propiedad estática,
      esta será considerada como distinta de la definida en la clase padre.
     </p>
    </div>
   <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">trait </span><span style="color: #0000BB">StaticExample<br /></span><span style="color: #007700">{<br />    public static </span><span style="color: #0000BB">$counter </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">T</span><span style="color: #007700">;<br /><br />    public static function </span><span style="color: #0000BB">incrementCounter</span><span style="color: #007700">()<br />    {<br />        static::</span><span style="color: #0000BB">$counter</span><span style="color: #007700">++;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">T</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">incrementCounter</span><span style="color: #007700">();<br /><br />echo </span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">$counter</span><span style="color: #007700">, </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">$counter</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>Resultado del ejemplo anterior en PHP 8.3:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
2
1
</pre></div>
    </div>
  </div>
 </div>
 <div class="sect2" id="language.oop5.traits.properties">
   <h3 class="title">Propiedades</h3>
   <p class="para">
    Los traits también pueden definir propiedades.
   </p>
   <div class="example" id="language.oop5.traits.properties.example">
    <p><strong>Ejemplo #12 Definir propiedades</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">trait </span><span style="color: #0000BB">PropertiesTrait<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$x </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">PropertiesExample<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">PropertiesTrait</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= new </span><span style="color: #0000BB">PropertiesExample</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">x</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
    <p class="para">
     Si un trait define una propiedad, entonces la clase no puede definir una
     propiedad con el mismo nombre a menos que sea compatible (misma visibilidad, tipo,
     modificador readonly, valor inicial), de lo contrario se produce un error fatal.
    </p>
   <div class="example" id="language.oop5.traits.properties.conflicts">
    <p><strong>Ejemplo #13 Resolución de conflictos</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">PropertiesTrait </span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$same </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">$different1 </span><span style="color: #007700">= </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">bool $different2</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">bool $different3</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">PropertiesExample </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">PropertiesTrait</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">$same </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">$different1 </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal error<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">string $different2</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal error<br />    </span><span style="color: #007700">readonly protected </span><span style="color: #0000BB">bool $different3</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal error<br /></span><span style="color: #007700">}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </div>

 <div class="sect2" id="language.oop5.traits.constants">
  <h3 class="title">Constantes</h3>
  <p class="para">
   Los traits pueden, a partir de PHP 8.2.0, también definir constantes.
  </p>
  <div class="example" id="language.oop5.traits.constants.example">
   <p><strong>Ejemplo #14 Trait definiendo una constante</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">ConstantsTrait </span><span style="color: #007700">{<br />    public const </span><span style="color: #0000BB">FLAG_MUTABLE </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />    final public const </span><span style="color: #0000BB">FLAG_IMMUTABLE </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">ConstantsExample </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">ConstantsTrait</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= new </span><span style="color: #0000BB">ConstantsExample</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$example</span><span style="color: #007700">::</span><span style="color: #0000BB">FLAG_MUTABLE</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
1
</pre></div>
    </div>
  </div>
  <p class="para">
   Si un trait define una constante, entonces una clase no puede definir una
   constante con el mismo nombre, a menos que sea compatible (misma
   visibilidad, mismo valor, etc.), de lo contrario se produce un error fatal.
  </p>
  <div class="example" id="language.oop5.traits.constants.conflicts">
   <p><strong>Ejemplo #15 Resolución de conflicto</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">trait </span><span style="color: #0000BB">ConstantsTrait </span><span style="color: #007700">{<br />    public const </span><span style="color: #0000BB">FLAG_MUTABLE </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />    final public const </span><span style="color: #0000BB">FLAG_IMMUTABLE </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">ConstantsExample </span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">ConstantsTrait</span><span style="color: #007700">;<br />    public const </span><span style="color: #0000BB">FLAG_IMMUTABLE </span><span style="color: #007700">= </span><span style="color: #0000BB">5</span><span style="color: #007700">; </span><span style="color: #FF8000">// Fatal error<br /></span><span style="color: #007700">}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </div>
  <div class="sect2" id="language.oop5.traits.final-methods">
   <h3 class="title">Métodos finales</h3>
   <p class="simpara">
    A partir de PHP 8.3.0, el modificador <a href="language.oop5.final.php" class="link">final</a>
    puede ser aplicado usando el operador <code class="literal">as</code>
    a los métodos importados desde los traits. Esto puede ser usado para impedir
    que las clases hijas sobrecarguen el método. Sin embargo, la clase que usa
    el trait puede seguir sobrecargando el método.
   </p>
   <div class="example" id="language.oop5.traits.final-methods.example">
    <p><strong>Ejemplo #16 Definir un método proveniente de un trait como <code class="literal">final</code></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">trait </span><span style="color: #0000BB">CommonTrait<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">method</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #DD0000">'Hello'</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">FinalExampleA<br /></span><span style="color: #007700">{<br />    use </span><span style="color: #0000BB">CommonTrait </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">CommonTrait</span><span style="color: #007700">::</span><span style="color: #0000BB">method </span><span style="color: #007700">as final; </span><span style="color: #FF8000">// El 'final' impide que las clases hijas sobrecarguen el método<br />    </span><span style="color: #007700">}<br />}<br /><br />class </span><span style="color: #0000BB">FinalExampleB </span><span style="color: #007700">extends </span><span style="color: #0000BB">FinalExampleA<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">method</span><span style="color: #007700">() {}<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    <div class="example-contents"><p>Resultado del ejemplo anterior es similar a:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
Fatal error: Cannot override final method FinalExampleA::method() in ...
</pre></div>
    </div>
   </div>
  </div>

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