1
0
mirror of https://github.com/php/doc-es.git synced 2026-03-24 07:22:16 +01:00
Files
archived-doc-es/language/oop5/overloading.xml
2025-05-06 21:45:14 +02:00

328 lines
11 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: d6f54016d62904cfd8200604aadd5e3f0d9bad97 Maintainer: PhilDaiguille Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.oop5.overloading" xmlns="http://docbook.org/ns/docbook">
<title>Sobrecarga mágica</title>
<para>
La sobrecarga mágica en PHP permite "crear" dinámicamente propiedades y métodos. Estas entidades dinámicas son
tratadas a través de métodos mágicos establecidos que se pueden posicionar
en una clase para diversos tipos de acciones.
</para>
<para>
Los métodos mágicos de sobrecarga son llamados durante la interacción
con propiedades o métodos que no han sido declarados
o no son <link linkend="language.oop5.visibility">visibles</link>
en el contexto actual. El resto de esta sección utiliza
los términos de <quote>propiedades inaccesibles</quote> y de
<quote>métodos inaccesibles</quote> para referirse a esta
combinación de declaración y visibilidad.
</para>
<para>
Todos los métodos mágicos de sobrecarga deben ser definidos como
<literal>public</literal>.
</para>
<note>
<para>
Ninguno de los argumentos de estos métodos mágicos puede ser
<link linkend="functions.arguments.by-reference">pasado por
referencia</link>.
</para>
</note>
<note>
<para>
La interpretación PHP de la <quote>sobrecarga</quote> es
diferente de la de la mayoría de los lenguajes orientados a objetos. La sobrecarga, habitualmente, proporciona la posibilidad de tener
varios métodos con el mismo nombre pero con una cantidad
y tipos diferentes de argumentos.
</para>
</note>
<sect2 xml:id="language.oop5.overloading.members">
<title>Sobrecarga de propiedades</title>
<methodsynopsis xml:id="object.set">
<modifier>public</modifier> <type>void</type><methodname>__set</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>mixed</type><parameter>value</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.get">
<modifier>public</modifier> <type>mixed</type><methodname>__get</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.isset">
<modifier>public</modifier> <type>bool</type><methodname>__isset</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.unset">
<modifier>public</modifier> <type>void</type><methodname>__unset</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
</methodsynopsis>
<para>
<link linkend="object.set">__set()</link> es solicitada al escribir datos
hacia propiedades inaccesibles (protegidas o privadas) o no existentes.
</para>
<para>
<link linkend="object.get">__get()</link> es llamada para leer datos desde
propiedades inaccesibles (protegidas o privadas) o no existentes.
</para>
<para>
<link linkend="object.isset">__isset()</link> es solicitada cuando
<function>isset</function> o <function>empty</function> son llamadas sobre
propiedades inaccesibles (protegidas o privadas) o no existentes.
</para>
<para>
<link linkend="object.unset">__unset()</link> es invocada cuando
<function>unset</function> es llamada sobre propiedades inaccesibles
(protegidas o privadas) o no existentes.
</para>
<para>
El argumento <varname>$name</varname> es el nombre de la propiedad con la que se interactúa.
El argumento <varname>$value</varname> del método <link linkend="object.set">__set()</link>
especifica el valor al que la propiedad <varname>$name</varname> debería ser definida.
</para>
<para>
La sobrecarga de propiedades solo funciona en contextos de objeto.
Estos métodos mágicos no serán lanzados en contexto estático.
Por consiguiente, estos métodos no deberían ser declarados como
<link linkend="language.oop5.static">estáticos</link>.
Se lanza un aviso si alguno de los métodos mágicos es declarado como estático.
</para>
<note>
<para>
El valor devuelto por <link linkend="object.set">__set()</link>
es ignorado debido a la forma en que PHP trata el operador de asignación.
De la misma manera, <link linkend="object.get">__get()</link> nunca es llamada durante
una asignación encadenada, como esta:
<literal><![CDATA[ $a = $obj->b = 8; ]]></literal>
</para>
</note>
<note>
<para>
PHP no llamará a un método sobrecargado desde el mismo método sobrecargado.
Esto significa, por ejemplo, que escribir <code>return $this->foo</code> dentro
de <link linkend="object.get">__get()</link> devolverá <literal>null</literal>
y lanzará un <constant>E_WARNING</constant> si no hay una propiedad <literal>foo</literal> definida,
en lugar de llamar a <link linkend="object.get">__get()</link> una segunda vez.
Sin embargo, los métodos de sobrecarga pueden invocar otros métodos de sobrecarga de manera implícita
(por ejemplo, <link linkend="object.set">__set()</link> desencadenando <link linkend="object.get">__get()</link>).
</para>
</note>
<example>
<title>Ejemplo de sobrecarga de propiedades con los métodos
<link linkend="object.get">__get()</link>,
<link linkend="object.set">__set()</link>,
<link linkend="object.isset">__isset()</link> y
<link linkend="object.unset">__unset()</link>
</title>
<programlisting role="php">
<![CDATA[
<?php
class PropertyTest
{
/** Variable para los datos sobrecargados. */
private $data = array();
/** La sobrecarga no es utilizada en las propiedades declaradas. */
public $declared = 1;
/** La sobrecarga solo es lanzada cuando se accede a esta propiedad desde fuera de la clase. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Definición de '$name' al valor '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Recuperación de '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Propiedad no definida vía __get() : ' . $name .
' en ' . $trace[0]['file'] .
' en la línea ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
public function __isset($name)
{
echo "¿Está '$name' definido?\n";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Borrado de '$name'\n";
unset($this->data[$name]);
}
/** Este no es un método mágico, necesario aquí solo para el ejemplo. */
public function getHidden()
{
return $this->hidden;
}
}
$obj = new PropertyTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Manipulemos ahora la propiedad privada llamada 'hidden' :\n";
echo "'hidden' es visible desde la clase, por lo que __get() no es utilizado...\n";
echo $obj->getHidden() . "\n";
echo "'hidden' no es visible fuera de la clase, por lo que __get() es utilizado...\n";
echo $obj->hidden . "\n";
?>
]]>
</programlisting>
&example.outputs;
<screen role="php">
<![CDATA[
Definición de 'a' a '1'
Recuperación de 'a'
1
¿Está 'a' definido?
bool(true)
Borrado de 'a'
¿Está 'a' definido?
bool(false)
1
Manipulemos ahora la propiedad privada llamada 'hidden' :
'hidden' es visible desde la clase, por lo que __get() no es utilizado...
2
'hidden' no es visible fuera de la clase, por lo que __get() es utilizado...
Recuperación de 'hidden'
Notice: Propiedad no definida vía __get() : hidden en <file> en la línea 64 en <file> en la línea 28
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.overloading.methods">
<title>Sobrecarga de métodos</title>
<methodsynopsis xml:id="object.call">
<modifier>public</modifier> <type>mixed</type><methodname>__call</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>array</type><parameter>arguments</parameter></methodparam>
</methodsynopsis>
<methodsynopsis xml:id="object.callstatic">
<modifier>public static</modifier> <type>mixed</type><methodname>__callStatic</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam><type>array</type><parameter>arguments</parameter></methodparam>
</methodsynopsis>
<para>
<link linkend="object.call">__call()</link> es llamada cuando se invoca
métodos inaccesibles en un contexto de objeto.
</para>
<para>
<link linkend="object.callstatic">__callStatic()</link> es lanzada cuando se invoca
métodos inaccesibles en un contexto estático.
</para>
<para>
El argumento <varname>$name</varname> es el nombre del método llamado.
El argumento <varname>$arguments</varname> es un array que contiene
los parámetros pasados al método <varname>$name</varname>.
</para>
<example>
<title>Sobrecarga de métodos con
<link linkend="object.call">__call()</link> y
<link linkend="object.callstatic">__callStatic()</link></title>
<programlisting role="php">
<![CDATA[
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// Nota: el valor de $name es sensible a mayúsculas y minúsculas.
echo "Llamada al método '$name' "
. implode(', ', $arguments). "\n";
}
public static function __callStatic($name, $arguments)
{
// Nota: el valor de $name es sensible a mayúsculas y minúsculas.
echo "Llamada al método estático '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('en un contexto de objeto');
MethodTest::runTest('en un contexto static');
?>
]]>
</programlisting>
&example.outputs;
<screen role="php">
<![CDATA[
Llamada al método 'runTest' en un contexto de objeto
Llamada al método estático 'runTest' en un contexto static
]]>
</screen>
</example>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->