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

contributors($setup);

?>
<div id="language.oop5.anonymous" class="sect1">
 <h2 class="title">Clases anónimas</h2>

 <p class="para">
  Las clases anónimas son útiles cuando se necesita crear objetos únicos simples.
 </p>

 <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: #FF8000">// Utilizando una clase explícita<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Logger<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">log</span><span style="color: #007700">(</span><span style="color: #0000BB">$msg</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #0000BB">$msg</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$util</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setLogger</span><span style="color: #007700">(new </span><span style="color: #0000BB">Logger</span><span style="color: #007700">());<br /><br /></span><span style="color: #FF8000">// Utilizando una clase anónima<br /></span><span style="color: #0000BB">$util</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setLogger</span><span style="color: #007700">(new class {<br />    public function </span><span style="color: #0000BB">log</span><span style="color: #007700">(</span><span style="color: #0000BB">$msg</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #0000BB">$msg</span><span style="color: #007700">;<br />    }<br />});</span></span></code></div>
  </div>

 </div>

 <p class="para">
  Se les pueden pasar argumentos a través del constructor, pueden extender otras clases, implementar interfaces o utilizar traits como con una clase normal.
 </p>

 <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">SomeClass </span><span style="color: #007700">{}<br />interface </span><span style="color: #0000BB">SomeInterface </span><span style="color: #007700">{}<br />trait </span><span style="color: #0000BB">SomeTrait </span><span style="color: #007700">{}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(new class(</span><span style="color: #0000BB">10</span><span style="color: #007700">) extends </span><span style="color: #0000BB">SomeClass </span><span style="color: #007700">implements </span><span style="color: #0000BB">SomeInterface </span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$num</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">$num</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">num </span><span style="color: #007700">= </span><span style="color: #0000BB">$num</span><span style="color: #007700">;<br />    }<br /><br />    use </span><span style="color: #0000BB">SomeTrait</span><span style="color: #007700">;<br />});</span></span></code></div>
  </div>

  <p class="para">El ejemplo anterior mostrará:</p>
  <div class="example-contents screen">
<div class="cdata"><pre>
object(class@anonymous)#1 (1) {
  [&quot;Command line code0x104c5b612&quot;:&quot;class@anonymous&quot;:private]=&gt;
  int(10)
}
</pre></div>
  </div>
 </div>

 <p class="para">
  Anidar una clase anónima dentro de otra clase no da acceso a los métodos o propiedades privadas o protegidas de la clase contenedora. Para utilizar métodos o propiedades protegidas de la clase contenedora, la clase anónima debe extenderla. Para utilizar las propiedades privadas de la clase contenedora en la clase anónima, estas deben ser pasadas a través del constructor.
 </p>

 <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">Outer<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$prop </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">$prop2 </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /><br />    protected function </span><span style="color: #0000BB">func1</span><span style="color: #007700">()<br />    {<br />        return </span><span style="color: #0000BB">3</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">func2</span><span style="color: #007700">()<br />    {<br />        return new class(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop</span><span style="color: #007700">) extends </span><span style="color: #0000BB">Outer </span><span style="color: #007700">{<br />            private </span><span style="color: #0000BB">$prop3</span><span style="color: #007700">;<br /><br />            public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">$prop</span><span style="color: #007700">)<br />            {<br />                </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop3 </span><span style="color: #007700">= </span><span style="color: #0000BB">$prop</span><span style="color: #007700">;<br />            }<br /><br />            public function </span><span style="color: #0000BB">func3</span><span style="color: #007700">()<br />            {<br />                return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop2 </span><span style="color: #007700">+ </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop3 </span><span style="color: #007700">+ </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">func1</span><span style="color: #007700">();<br />            }<br />        };<br />    }<br />}<br /><br />echo (new </span><span style="color: #0000BB">Outer</span><span style="color: #007700">)-&gt;</span><span style="color: #0000BB">func2</span><span style="color: #007700">()-&gt;</span><span style="color: #0000BB">func3</span><span style="color: #007700">();</span></span></code></div>
  </div>

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

 <p class="para">
  Todos los objetos creados por la misma declaración de clase anónima son instancias de la misma clase.
 </p>

 <div class="informalexample">
  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">anonymous_class</span><span style="color: #007700">()<br />{<br />    return new class {};<br />}<br /><br />if (</span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">anonymous_class</span><span style="color: #007700">()) === </span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">anonymous_class</span><span style="color: #007700">())) {<br />    echo </span><span style="color: #DD0000">'same class'</span><span style="color: #007700">;<br />} else {<br />    echo </span><span style="color: #DD0000">'different class'</span><span style="color: #007700">;<br />}</span></span></code></div>
 </div>

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

 <blockquote class="note"><p><strong class="note">Nota</strong>: 
  <p class="para">
   Tenga en cuenta que las clases anónimas son asignadas un nombre por el motor, como se ilustra en el siguiente ejemplo. Este nombre debe considerarse como un detalle de implementación, que no debe ser invocado.
  </p>
  <div class="informalexample">
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">echo </span><span style="color: #0000BB">get_class</span><span style="color: #007700">(new class {});</span></span></code></div>
  </div>

  <p class="para">Resultado del ejemplo anterior es similar a:</p>
  <div class="example-contents screen">
<div class="cdata"><pre>
class@anonymous/in/oNi1A0x7f8636ad2021
</pre></div>
   </div>
  </div>
 </p></blockquote>
 <div class="sect2" id="language.oop5.anonymous.readonly">
  <h3 class="title">Clases anónimas de solo lectura</h3>
  <p class="simpara">
   A partir de PHP 8.3.0, el modificador <code class="literal">readonly</code> puede ser aplicado a las clases anónimas.
  </p>
  <div class="example" id="language.oop5.anonymous.readonly.example">
   <p><strong>Ejemplo #1 Definir una clase anónima de solo lectura</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: #FF8000">// Utilización de una clase anónima<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(new readonly class(</span><span style="color: #DD0000">'[DEBUG]'</span><span style="color: #007700">) {<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(private </span><span style="color: #0000BB">string $prefix</span><span style="color: #007700">)<br />    {<br />    }<br /><br />    public function </span><span style="color: #0000BB">log</span><span style="color: #007700">(</span><span style="color: #0000BB">$msg</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prefix </span><span style="color: #007700">. </span><span style="color: #DD0000">' ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$msg</span><span style="color: #007700">;<br />    }<br />});</span></span></code></div>
   </div>

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