1
0
mirror of https://github.com/php/doc-es.git synced 2026-03-26 00:12:06 +01:00
Files
archived-doc-es/language/oop5/basic.xml
Pedro Antonio Gil Rodríguez de5c63a90e Actualización a la última versión
git-svn-id: https://svn.php.net/repository/phpdoc/es/trunk@338503 c90b9560-bf6c-de11-be94-00142212c4b1
2016-01-15 14:45:08 +00:00

416 lines
11 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 45fc246e9fa66e3eed77c124f1c7d1681cf46cb1 Maintainer: seros Status: ready -->
<!-- Reviewed: yes Maintainer: seros -->
<sect1 xml:id="language.oop5.basic" xmlns="http://docbook.org/ns/docbook">
<title>Lo básico</title>
<sect2 xml:id="language.oop5.basic.class">
<title>class</title>
<para>
La definición básica de una clase comienza con la palabra
reservada <literal>class</literal>, seguido de un nombre de clase,
y continuando con un par de llaves que encierran las definiciones
de las propiedades y métodos pertenecientes a dicha clase.
</para>
<para>
El nombre de clase puede ser cualquier etiqueta válida, siempre que no sea
una <link linkend="reserved">palabra reservada</link> de PHP. Un nombre válido
de clase comienza con una letra o un guión bajo, seguido de una cantidad arbitraria de
letras, números o guiones bajos. Como expresión regular, se
expresaría de la siguiente forma:
<literal>^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$</literal>.
</para>
<para>
Una clase puede tener sus propias
<link linkend="language.oop5.constants">constantes</link>, <link linkend="language.oop5.properties">variables</link>
(llamadas "propiedades"), y funciones (llamados "métodos").
</para>
<example>
<title>Definición de una clase sencilla</title>
<programlisting role="php">
<![CDATA[
<?php
class ClaseSencilla
{
// Declaración de una propiedad
public $var = 'un valor predeterminado';
// Declaración de un método
public function mostrarVar() {
echo $this->var;
}
}
?>
]]>
</programlisting>
</example>
<para>
La pseudovariable <varname>$this</varname> está disponible cuando un
método es invocado dentro del contexto de un
objeto. <varname>$this</varname> es una referencia al objeto
invocador (usualmente el objeto al cual el método pertenece, aunque
puede que sea otro objeto si el método es llamado
<link linkend="language.oop5.static">estáticamente</link> desde el contexto
de un objeto secundario).
</para>
<para>
<example xml:id="language.oop5.basic.class.this">
<title>Algunos ejemplos de la pseudovariable <varname>$this</varname></title>
<programlisting role="php">
<![CDATA[
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this está definida (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this no está definida.\n";
}
}
}
class B
{
function bar()
{
// Nota: la siguiente línea arrojará una advertencia si E_STRICT está habilitado.
A::foo();
}
}
$a = new A();
$a->foo();
// Nota: la siguiente línea arrojará una advertencia si E_STRICT está habilitado.
A::foo();
$b = new B();
$b->bar();
// Nota: la siguiente línea arrojará una advertencia si E_STRICT está habilitado.
B::bar();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
$this está definida (A)
$this no está definida.
$this está definida (B)
$this no está definida.
]]>
</screen>
</example>
</para>
</sect2>
<sect2 xml:id="language.oop5.basic.new">
<title>new</title>
<para>
Para crear una instancia de una clase, se debe emplear la palabra reservada
<literal>new</literal>. Un objeto se creará siempre a menos que el objeto tenga un
<link linkend="language.oop5.decon">constructor</link> que arroje una
<link linkend="language.exceptions">excepción</link> en caso de error. Las
clases deberían ser definidas antes de la instanciación (y en algunos casos
esto es un requerimiento).
</para>
<para>
Si se emplea un <type>string</type> que contenga el nombre de una clase con
<literal>new</literal>, se creará una nueva instancia de esa clase. Si
la clase estuviera en un espacio de nombres, se debe utilizar su nombre completo
al realizar esto.
</para>
<example>
<title>Creación de una instancia</title>
<programlisting role="php">
<![CDATA[
<?php
$instancia = new ClaseSencilla();
// Esto también se puede hacer con una variable:
$nombreClase = 'ClaseSencilla';
$instancia = new $nombreClase(); // new ClaseSencilla()
?>
]]>
</programlisting>
</example>
<para>
En el contexto de una clase, es posible crear un nuevo objeto con
<literal>new self</literal> y <literal>new parent</literal>.
</para>
<para>
Cuando se asigna una instancia ya creada de una clase a una nueva variable, ésta última
accederá a la misma instancia que el objeto que le fue asignado. Esta
conducta es la misma que cuando se pasan instancias a una función. Se puede
realizar una copia de un objeto ya creado a través de la
<link linkend="language.oop5.cloning">clonación</link> del mismo.
</para>
<example>
<title>Asignación de objetos</title>
<programlisting role="php">
<![CDATA[
<?php
$instancia = new ClaseSencilla();
$asignada = $instancia;
$referencia =& $instancia;
$instancia->var = '$asignada tendrá este valor';
$instancia = null; // $instancia y $referencia son null
var_dump($instancia);
var_dump($referencia);
var_dump($asignada);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
NULL
NULL
object(ClaseSencilla)#1 (1) {
["var"]=>
string(27) "$asignada tendrá este valor"
}
]]>
</screen>
</example>
<para>
PHP 5.3.0 introdujo un par de formas nuevas para crear instancias de un
objeto:
</para>
<example>
<title>Creación de nuevos objetos</title>
<programlisting role="php">
<![CDATA[
<?php
class Prueba
{
static public function getNew()
{
return new static;
}
}
class Hija extends Prueba
{}
$obj1 = new Prueba();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);
$obj3 = Prueba::getNew();
var_dump($obj3 instanceof Prueba);
$obj4 = Hija::getNew();
var_dump($obj4 instanceof Hija);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
bool(true)
bool(true)
bool(true)
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.basic.properties-methods">
<title>Properties and methods</title>
<para>
Las propiedades y métodos de una clase viven en «espacios de nombres» diferentes, por tanto, es
posible tener una propiedad y un método con el mismo nombre. Al hacer referencia tanto
a una propideada como a un método se utiliza la misma notación, y si se accederá a la
propiedad o se llamará al método, solamente depende del contexto,
es decir, si el empleo es el acceso a una variable o la llamada a una función.
</para>
<example>
<title>Acceso a propiedad contra llamada a método</title>
<programlisting role="php">
<![CDATA[
class Foo
{
public $bar = 'propiedad';
public function bar() {
return 'método';
}
}
$obj = new Foo();
echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
propiedad
método
]]>
</screen>
</example>
<para>
Esto significa que llamar a una <link linkend="functions.anonymous">función
anónima</link> que ha sido asignada a una propiedad no es posible
directamte. En su lugar, la propiedad ha de ser asignada primero a una variable, por
ejemplo.
</para>
<example>
<title>Llamar a una función anónima almacenada en una propiedad</title>
<programlisting role="php">
<![CDATA[
class Foo
{
public $bar;
public function __construct() {
$this->bar = function() {
return 42;
};
}
}
$obj = new Foo();
$func = $obj->bar;
echo $func(), PHP_EOL;
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
42
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.basic.extends">
<title>extends</title>
<para>
Una clase puede heredar los métodos y propiedades de otra clase
empleando la palabra reservada <literal>extends</literal> en la declaración
de la clase. No es posible la extensión de múltiples clases; una clase
sólo puede heredar de una clase base.
</para>
<para>
Los métodos y propiedades heredados pueden ser sobrescritos
con la redeclaración de éstos utilizando el mismo nombre que en
la clase madre. Sin embargo, si la clase madre definió un método
como <link linkend="language.oop5.final">final</link>, éste no
podrá ser sobrescrito. Es posible acceder a los métodos
sobrescritos o a las propiedades estáticas haciendo referencia a ellos
con <link linkend="language.oop5.paamayim-nekudotayim">parent::</link>.
</para>
<para>
Cuando se sobrescriben métodos, la firma de los parámetros debería ser la misma o
PHP generará un error de nivel <constant>E_STRICT</constant>. Esto no se
aplica a los constructores, los cuales permiten la sobrescritura con diferentes
parámetros.
</para>
<example>
<title>Herencia de clases sencilla</title>
<programlisting role="php">
<![CDATA[
<?php
class ClaseExtendida extends ClaseSencilla
{
// Redefinición del método padre
function mostrarVar()
{
echo "Clase extendida\n";
parent::mostrarVar();
}
}
$extendida = new ClaseExtendida();
$extendida->mostrarVar();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Clase extendida
un valor predeterminado
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.basic.class.class">
<title>::class</title>
<para>
Desde PHP 5.5, también se emplea la palabra reservada <literal>class</literal> para la resolución
de nombres de clases. Se puede obtener un string con el nombre completamente cualificado
de la clase <literal>NombreClase</literal> utilizando
<literal>NombreClase::class</literal>. Esto es particularmete útil con
clases en <link linkend="language.namespaces">espacios de nombres</link>.
</para>
<para>
<example xml:id="language.oop5.basic.class.name">
<title>Resolución de nombres de clases</title>
<programlisting role="php">
<![CDATA[
<?php
namespace NS {
class NombreClase {
}
echo NombreClase::class;
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
NS\NombreClase
]]>
</screen>
</example>
</para>
<note>
<para>La resolución de nombres de clases con <literal>::class</literal> es una transformación
durante la compilación. Esto significa que, en el instante de crear el string del nombre
de la clase, aún no se ha realizado ninguna autocarga. Como consecuencia, los nombres de clases
se expanden incluso si la clase no existe. No se emite ningún error en tal
caso.
</para>
</note>
</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
-->