Desarrollo de aplicaciones web con PHP y MySQL
Clases y Objetos en PHP
Sergio Sáez y José Luis Poza
© 2015 Sergio Sáez y José Luis Poza
1. Introduccion
- Wikipedia
- La programación orientada a objetos (OOP) es un paradigma de programación que usa los objetos en sus interacciones, para diseñar aplicaciones y programas informáticos.
Está basado en varias técnicas, incluyendo herencia, cohesión, abstracción, polimorfismo, acoplamiento y encapsulamiento.
- En PHP el soporte para OOP, desde la versión 5, está fuertemente influenciado por el lenguaje Java.
- PHP tiene algunas extensiones interesantes por ser un lenguaje interpretado.
<?php
class ClaseSimple {
// Declaración de una propiedad
public $var = 'Un valor inicial';
// Declaración de un método
function muestraVar() {
echo "Dentro: " . $this->var . "\n";
}
}
$obj= new ClaseSimple;
$obj->muestraVar();
echo "Fuera: " . $obj->var . "\n";
?>
Dentro: Un valor inicial
Fuera: Un valor inicial
2. Creación de objetos
|
<?php class UnaClase { public $var= "Un valor inicial"; static public function getNew() { return new static; } }
// Con el nombre de la clase $obj1= new UnaClase; var_dump($obj1);
// A partir de otro objeto $obj2= new $obj1; var_dump($obj2);
// Con un método estático $obj3= UnaClase::getNew(); var_dump($obj3); ?>
|
object(UnaClase)#1 (1) {
["var"]=>
string(16) "Un valor inicial"
}
object(UnaClase)#2 (1) {
["var"]=>
string(16) "Un valor inicial"
}
object(UnaClase)#3 (1) {
["var"]=>
string(16) "Un valor inicial"
}
- Se utiliza la palabra clave new para crear instancias u objetos de una clase dada.
|
|
<?php class UnaClase { public $var; function __construct($val) { $this->var= "Valor: $val"; } static public function getNew($val) { return new static($val); } } $i= 0;
$obj1= new UnaClase($i++); var_dump($obj1);
$obj2= new $obj1($i++); var_dump($obj2);
$obj3= UnaClase::getNew($i++); var_dump($obj3); ?>
|
object(UnaClase)#1 (1) {
["var"]=>
string(8) "Valor: 0"
}
object(UnaClase)#2 (1) {
["var"]=>
string(8) "Valor: 1"
}
object(UnaClase)#3 (1) {
["var"]=>
string(8) "Valor: 2"
}
- Se puede inicializar el objeto con un método __construct.
- El constructor puede recibir parámetros.
|
3. Herencia
|
<?php class ClaseExtendida extends ClaseSimple { // Redefine el método del padre function muestraVar() { echo "Clase extendida\n"; parent::muestraVar(); } }
$extendida = new ClaseExtendida(); $extendida->muestraVar(); ?>
|
Clase extendida
Dentro: Un valor inicial
|
- Se extiende una clase ancestro con la palabra clave extends.
- Se pueden añadir nuevos métodos o sobreescribir los métodos originales.
- Con la palabra clave final se puede indicar que una clase no se puede extender.
4. Atributos y visibilidad
- La visibilidad de un atributo puede ser:
- public
- Atributo público. Es la visibilidad por omisión.
- protected
- Atributo con acceso desde las clases hijas
- private
- Atributo privado del objeto
- Una clase puede tener constantes, atributos de clase y de instancia.
- Las constante de clase se especifican con const y sin el $ delante.
- Los atributos de clase se especifican con static.
- En cualquier otro caso es una atributo de instancia.
- Las constantes y atributos de clase se acceden con self::, desde los métodos de la clase, y con NombreClase:: o $objeto:: desde el exterior (si son públicos).
- Las atributos de instancia se acceden con $this->, desde los métodos de la clase, y con $objeto-> desde el exterior (si son públicos).
|
<?php class UnaClase { const STAT = 'CONST'; static $stat = 'Static'; public $publ = 'Public'; protected $prot = 'Protected'; private $priv = 'Private';
public function muestraAtributos( ){ echo 'self::STAT: '. self::STAT; echo '<br>self::$stat: '. self::$stat; // echo '<br>$this->stat: '. $this->stat; // No se puede acceder con $this a $stat echo '<br>$this->priv: '. $this->priv; echo '<br>$this->prot: '. $this->prot; echo '<br>$this->publ: '. $this->publ; } } $obj = new UnaClase(); $obj->muestraAtributos(); ?>
|
self::STAT: CONST self::$stat: Static $this->priv: Private $this->prot: Protected $this->publ: Public
|
<?php
class ClaseExtendida extends UnaClase {
public function muestraAtributos( ){
echo 'self::STAT: ' . self::STAT;
echo '<br> self::$stat: ' . self::$stat;
echo '<br>$this->priv: ' . $this->priv;
echo '<br>$this->prot: ' . $this->prot;
echo '<br>$this->publ: ' . $this->publ;
}
}
$obj = new ClaseExtendida();
$obj->muestraAtributos();
?>
self::STAT: CONST
self::$stat: StaticPHP Notice: Undefined property: ClaseExtendida::$priv in - on line 23
$this->priv:
$this->prot: Protected
$this->publ: Public
- La clase hija no tiene acceso a los atributos privados.
5. Métodos
- Se declarán como funciones dentro de la definición de una clase y tienen las mismas reglas de visibilidad que los atributos.
- Se pueden sobreescribir en las clases hijas.
- Los métodos heredados se pueden acceder desde un método de la clase hija con parent::método() o con ClaseAncestro::método() para métodos no heredados directamente.
- Con la plabra clave final se puede indicar que un método no puede ser sobreescrito por las clases hijas.
- Un método se puede declarar como abstract indicando que no está implementado y que se debe sobreescribir en una clase hija, con una visibilidad igual o mayor. En este caso, la clase también se debe declarar como abstract y no podrá instanciarse.
<?php
abstract class ClaseAbstracta {
abstract protected function obtenerValor();
public function imprimirValor() {
echo $this->obtenerValor() . "\n";
}
}
class ClaseConcreta extends ClaseAbstracta {
protected function obtenerValor() {
return "Un valor";
}
}
$obj= new ClaseConcreta();
$obj->imprimirValor();
echo $obj->obtenerValor(); // Fatal error. No se puede acceder
?>
Un valor
PHP Fatal error: Call to protected method ClaseConcreta::obtenerValor() from context '' i
6. Carga automática de clases
- PHP permite registrar una función encargada de incluir los ficheros de que contienen las definiciones de las nuevas clases.
<?php
function mi_cargador_de_clases($class) {
include 'classes/' . $class . '.class.php';
}
spl_autoload_register('mi_cargador_de_clases');
// O usando las funciones anónimas de PHP 5.3
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
});
$obj = new MiClase(); // Carga el fichero 'classes/MiClase.class.php'
?>
7. Métodos mágicos
- Existen algunos métodos mágicos con un comportamiento interesante.
<?php
// __set se ejecuta cuando se intenta escribir en un atributo inaccesible
public void __set ( string $name, mixed $value );
// __get se ejecuta cuando se intenta leer un atributo inaccesible
public mixed __get ( string $name );
// __isset se ejecuta cuando se invoca isset() o empty() sobre
// un atributo inaccesible
public bool __isset ( string $name );
// __unset se ejecuta cuando se invoca __unset sobre un atributo inaccesible
public void __unset ( string $name );
// __call se ejecuta cuando se invoca un método inaccesible
public mixed __call ( string $name , array $arguments );
- Todos reciben el nombre del atributo o método inaccesible.
- En el caso de __set recibe también el valor que se le intentaba asignar.
- En el caso de __call recibe también un vector con los parámetros.
|
<?php class ConjuntoDePropiedades { private $data = array();
public function __set($name, $value) { echo "Magic set: $name= $value;\n"; $this->data[$name] = $value; } public function __get($name) { if (array_key_exists($name, $this->data)) { echo "Magic get: $name;\n"; return $this->data[$name]; } return null; } } $obj = new ConjuntoDePropiedades;
$obj->a = "Hola mundo"; echo $obj->a . "\n";
|
Magic set: a= Hola mundo;
Magic get: a;
Hola mundo
|
8. Invocación y creación por nombre
- Se pueden instanciar clases e invocar métodos cuyos identificadores están almacenados en variables.
<?php
class ClaseSimple {
// Declaración de una propiedad
public $var = 'Un valor inicial';
// Declaración de un método
function muestraVar() {
echo $this->var . "\n";
}
}
$clase= "ClaseSimple";
$obj= new $clase;
$metodo= "muestraVar";
$obj->$metodo();
?>
Un valor inicial