Modelo de objetos en PHP5

Atributos y métodos de clase

Miembros static

Los atributos de clase reciben este nombre porque no pertenecen a un objeto en concreto, sino a la clase como entidad propia. En PHP los elementos de clase se definen mediante la palabra static.

static $atributoDeClase;

static function metodoDeClase()
{
  ...
}

El acceso a los atributos de clase se hace a través del operador de alcance ::

Clase::$atributo

Por ejemplo, se declara una clase con un atributo de clase (static) y un atributo normal de objeto:

class Estatica
{
//// atributos de clase
static $mensaje_estatico = "Hola, soy un atributo de clase";

//// atributos de objeto
var $mensaje_normal = "Yo soy un atributo de objeto";
}

Para acceder al atributo static no es necesario instanciar la clase:

//// acceso a $mensaje_estatico
//// (no se ha instanciado ningun objeto!!!)
echo Estatica::$mensaje_estatico;
//// Hola, soy un atributo de clase
echo "<br>";

Estatica::$mensaje_estatico = "Soy static";
echo
Estatica::$mensaje_estatico;
//// Soy static
echo "<br>";

Como es lógico, para acceder a un atributo normal (no static) es necesario hacerlo desde un objeto de la clase. Tampoco se puede acceder desde un objeto directamente a sus atributos estáticos:

//// ERROR: no se puede acceder a un atributo de objeto
//// sin instanciar la clase
echo Estatica::$mensaje_normal;
echo "<br>";

//// creamos un objeto Estatica
$objEstatic = new Estatica;


echo
$objEstatic->mensaje_estatico;
//// [ NO existe en este ambito ]
echo "<br>";

echo
$objEstatic->mensaje_normal;
//// Yo soy un atributo de objeto
echo
"<br>";

De la misma forma que existen atributos de clase, se pueden definir métodos de clase. Los métodos de clase (static) se pueden invocar sin necesidad de construir previamente un objeto.

También se pueden aplicar los cualificadores de acceso como a los demás métodos y atributos:

class Estatica
{
//// atributos de clase
static public $publico = "Hola, soy un atributo de clase (publico)";
static private
$privado = "Yo soy atributo de clase privado";

//// atributos de objeto
public $separador = ">>>>> ";

static public function
getPrivado ()
{
//// ERROR: no se puede acceder a un atributo
//// no estatico desde un metodo estatico
$this->separador.=" <<<<";

//// Correcto: devuelve la variable estatica $privado
return Estatica::$privado;
}
}

Los atributos privados static sólo serán accesibles desde el interior de la clase y sólo para métodos de clase (static):

//// acceso a $publico
echo Estatica::$publico;
echo
"<br>";

//// acceso directo a $privado: ERROR
echo Estatica::$privado;
echo "<br>";

//// acceso a traves de la interfaz publica
echo Estatica::getPrivado();
echo
"<br>";

En el siguiente ejemplo se implementa un contador de vehículos creados. El constructor se encarga de incrementar un contador (static) y el destructor se encarga de decrementarlo:

class Vehiculo
{
static private
$contadorVehiculos = 0;

function
__construct()
{
Vehiculo::$contadorVehiculos++;
return
true;
}

function
__destruct()
{
Vehiculo::$contadorVehiculos--;
return
true;
}

static public function
cuantosVehiculos()
{
return
Vehiculo::$contadorVehiculos;
}


}
//// fin de "Vehiculo"


//// creamos dos vehiculos
$coche1 = new Vehiculo();
$coche2 = new Vehiculo();

echo
"NUMERO VEHICULOS: ";
//// tambien: Vehiculo::cuantosVehiculos()
echo
$coche1->cuantosVehiculos();
//// NUMERO VEHICULOS: 2
echo
"<br>";

//// eliminamos un vehiculo
unset ($coche1);

echo
"NUMERO VEHICULOS: ";
//// tambien: Vehiculo::cuantosVehiculos()
echo
$coche2->cuantosVehiculos();
//// NUMERO VEHICULOS: 1
echo
"<br>";