sábado, 20 de diciembre de 2014

Las clases abstractas y las clases finales en PHP



  • Las clases abstractas
Las clases abstractas se escriben con la palabra clave abstract delante de la palabra class. Una clase abstracta no se puede instanciar, es decir, no permite crear una instancia. Puede escribir métodos abstractos, que son métodos donde solo escribe la firma precedida por la palabra clave abstract: abstract visibilidad function nombre_método (atributo tipo_atributo...). Estas clases solo sirven para obligar, a las clases que heredan de la clase abstracta, a reemplazar los métodos abstractos declarados en la clase abstracta.

En el siguiente ejemplo, la clase Animal es abstracta, ya que no se quiere crear (instanciar) animales, sino peces o gatos.

Añada también un método abstracto respira() en la clase Animal:

<?php
abstract class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//constantes de clase
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
// Declaración de la variable estática $contador
private static $contador = 0;
public function __construct($color, $peso) // Constructor
//que solicita 2 argumentos.
{
echo ’Llamada al constructor.<br />’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
self::$contador = self::$contador + 1;
}
//accesos
public function getColor()
{
return $this->color; //devuelve el color
}
public function setColor($color)
{
$this->color = $color; //escrito en el atributo color
}
public function getPeso()
{
return $this->peso; //devuelve el peso
}
public function setPeso($peso)
{
$this->peso = $peso; //escrito en el atributo peso
}
//métodos públicos
public function comer_animal(Animal $animal_comido)
{
//el animal que come aumenta su peso tanto como
//el del animal comido
$this->peso = $this->peso + $animal_comido->peso;
//el peso del animal comido y su color se restablecen a 0
$animal_comido->peso = 0;
$animal_comido->color = "";
}
public static function moverse()
{
echo "El animal se mueve.";
}
public function añadir_un_kilo()
{
$this->peso = $this->peso + 1;
}
// método estático que devuelve el valor del contador
public static function getContador()
{
return self::$contador;
}
//código no aplicado por el método abstracto
abstract public function respira();
}
?>

Observe que el método abstracto respira() no tiene cuerpo, es decir, no hay llaves {} en la aplicación del método.

Como las clases Pez y Gato heredan de la clase Animal, está obligado a definir de nuevo el método respira() en las clases Pez y Gato.

Debe añadir en la clase Pez lo siguiente:

public function respira()
{
echo "El pez respira.<br />";
}

Y en la clase Gato:

public function respira()
{
echo "El gato respira.<br />";
}

La página uso.php se convierte en:

<?php
//carga de clases
include(’Animal.class.php’);
include(’Pez.class.php’);
include(’Gato.class.php’);
//instanciar la clase Pez, que llama al constructor de
//la clase Animal
$pez = new Pez("gris",8);
//instanciar la clase Gato, que llama al constructor de
//la clase Animal
$gato = new Gato("blanco",4);
//llamada al método respira()
$pez->respira();
$gato->respira();
?>

Da como resultado:

Llamada al constructor.
Llamada al constructor.
El pez respira.
El gato respira.


  • Las clases finales
Cuando una clase es final, no se puede crear la clase hija que hereda de esta clase. Esto tiene poco interés práctico.

Debe añadir la palabra clave final delante de la palabra clave class.

Por ejemplo, si no crea una clase que hereda de la clase Pez, puede escribir final:

<?php
final class Pez extends Animal
{
private $vive en el mar; //tipo de pez
//accesos
...
//método
public function nadar()
{
echo "Nado <br />";
}
public function respira()
{
echo "El pez respira.<br />";
}
}
?>

También puede declarar los métodos finales. Estos métodos no se podrán sustituir.

En el párrafo dedicado a la sustitución hemos visto un ejemplo donde el método comer_animal(Animal $animal_comido) se ha sustituido en la clase Pez. Si este método era final en la clase Animal:

final public function comer_animal(Animal $animal_comido)
{
//el animal que come aumenta su peso tanto como
//el del animal comido
$this->peso = $this->peso + $animal_comido->peso;
//el peso del animal comido y su color se restablecen a 0
$animal_comido->peso = 0;
$animal_comido->color = "";
}

Por lo tanto, es imposible sustituir este método en la clase Pez.



Espero haber ayudado en algo. Hasta la próxima oportunidad!









No hay comentarios:

Publicar un comentario en la entrada