ES

www.codigo-facil.com > POO PHP, herencia

Programacion orientada a objetos en PHP


Parte 3 : Herencia

Capitulos

Programacion orientada a objetos en PHP, creacion de clases

Comentaremos las mejoras introducidas a partir de la version 5 del famoso lenguaje en lo que a la programacion orientada a objetos se refiere. Veremos como crear una clase en PHP y en que consiste un metodo estatico.

Programacion orientada a objetos en PHP, encapsulacion

En este articulo hablaremos con profundidad de los modificadores : public, private y protected.

Programacion orientada a objetos en PHP, herencia

En este capitulo hablaremos de la herencia en PHP, uno de los pilares fundamentales de la programacion orientada a objetos.

Programacion orientada a objetos en PHP, polimorfismo

En este capitulo vamos a hablar de otra de las principales caracteristicas dentro de la programacion orientada a objetos, el polimorfismo.

Programacion orientada a objetos en PHP, interfaces

En este capitulo veremos las interfaces en PHP, un mecanismo bastante utilizado en diferentes lenguajes de programacion para la implementacion del polimorfismo.

Programacion orientada a objetos en PHP, clases abstractas

En este capitulo veremos en que consiste y como crear una clase abstracta en PHP, ademas de sus principales diferencias respecto a las interfaces.

Introduccion.


La herencia es uno de los pilares fundamentales dentro de la programacion orientada a objetos. La herencia consiste en la definicion de una clase a partir de otra  existente, asi esta nueva clase se le llama clase extendida o clase derivada.

La importancia de la herencia reside en que cuando creamos una clase extendida, esta a su vez hereda todos los metodos y propiedades de su clase base o ancestra, pudiendo a su vez implementar otros metodos o propiedades exclusivos de nuestra clase extendida.

Un ejemplo nos ayudara a comprender en que consiste el concepto de herencia:
  1.  <?php
  2. /*
  3. Tomamos como base el ejemplo realizado en el capitulo anterior, relacionado con la conexion a una base de datos MySql.
  4. */
  5.  

  6. /* Creamos una clase base que nos sirva para controlar la conexion y la ejecucion de consultas */
  7. class ClassBD{
  8.   private $user = "";
  9.   privare $bd = "";
  10.   private $password = "";
  11.   private $host = "";

  12.   /*
  13.   Declaramos el metodo "conectar" y "desconectar" que sirve para realizar
  14.   la conexion a la bd, lo declaramos como private para que sea ejecutado
  15.   unicamente desde la propia clase
  16.   */
  17.   private function conectar()
  18.   {
  19.     if (@mysql_connect($this->host,$this->user,$this->password ) )
  20.     {
  21.       mysql_select_db( $this->bd );
  22.     }
  23.   }
  24.   private function desconectar()
  25.   {
  26.     mysql_close();
  27.   }

  28.   /*
  29.   Declaramos la funcion "execQuery" que nos permitira ejecutar
  30.   la consulta que le pasemos como parametro y nos devolvera
  31.   un array con los datos correspondientes.
  32.   */
  33.   protected function execQuery($sql)
  34.   {
  35.     $datos = array();
  36.     $this->conexion();
  37.     $recordset= mysql_query($sql);
  38.     if (@mysql_num_rows($recordset)>0)
  39.       while($tupla = mysql_fetch_assoc($recordset))
  40.       {
  41.         $temp[]=$tupla;
  42.       }
  43.     $this->disconnect();
  44.     return $datos;
  45.   }
  1. }
  2. ?>
Notas sobre el codigo :

En el codigo anterior hemos creado una clase base que nos sirve para controlar los accesos a una determinada base de datos.

Esto lo hemos conseguido gracias a la declaracion como private del metodo "conectar" y como protected el metodo "execQuery", lo que nos garantiza que ninguno de los 2 metodos pueden ser llamados desde fuera de la clase base o de sus extendidas para el caso de "execQuery". Abriendo la conexion unicamente para ejecutar la consulta y cerrandola despues evitando asi las consultas no controladas.

Pero en este punto muchos se preguntaran como hacemos para poder ejecutar una consulta, ya que ningun metodo es accesible desde fuera de la clase. Pues es en este momento que entra en juego el factor de la herencia, ya que en el siguiente ejemplo vamos a crear una clase para poder trabajar con una tabla en concreto.
  1. <?php
  2. /*
  3. Creamos la clase catalogo y decimos que su clase base es "classBD"
  4. */
  5. class ClassCatalogo extends classBD{

  6.   /*
  7.   Declaramos el metodo "getArt" que nos servira para poder
  8.   hacer consultas en este caso de la tabla articulos
  9.   */
  10.   public function getArt($select='*',$where='',$order='')
  11.   {
  12.     if ($where!='')
  13.       {
  14.       $where = ' WHERE '.$where;
  15.       }

  16.     if ($order!='')
  17.       {
  18.       $order = ' ORDER BY '.$order;
  19.       }
  20.     $sql = 'SELECT '.$select.' FROM articulo '.$where.$order;
  21.     return $this->execQuery($sql);
  22.   }
  1. }

  2. /*
  3. Una vez creada la clase, solo bastaria con crear el correspondiente
  4. objeto para poder interactura con la BD
  5. */
  6. $artObj = new ClassCatalogo;

  7. //Extraigo los datos de la tabla articulo y en caso
  8. //de existir datos imprimo por pantalla el nombre
  9. $datos = $artObj->getArt();
  10. while (count($datos) amp;amp; $tupla = each($datos))
  11. {
  12.   echo $tupla[1]['nombre'].'<br/>';
  13. }
  14. ?>
Notas sobre el codigo :

En este ultimo ejemplo hemos creado la clase extendida "classCatalogo" indicando que su clase base es "ClassBD", de esta forma dentro de esta clase podemos incluir lo metodos necesarios para interactura con la base de datos, y dar unicamente acceso a las tablas que creamos convenientes,  implmentando dentro de la clase metodos para acceder a unas posibles tablas de articulos, categorias, tipos, etc.

De esta forma hemos creado una capa entre el programador y nuestra base de datos que nos proporciona un control de acceso y ejecucion a la misma.

Redefiniendo metodos


Redifinir un metodo quiere decir volver a codificarlo, es decir volver a escribir el codigo de un metodo en la clase extendida que lo implementa.

La practica de redifinir metodos es algo bastante en los mecanismos de herencia dentro de la programacion orientada a objetos, y se realiza bien para completar las acciones del metodo que realiza la clase base o bien para realizar tareas totalmente diferentes a las que realiza su ancestro.

La implementacion de la redifinicion varia segun el lenguaje de programacion, en PHP es bastante sencilla, basta con volver a escribir el metodo en nuestra clase extendida. Solo destacar como apunte, anque no sea el caso de PHP, que en otros lenguajes de programacion mas estrictos, seria necesario respetar la declaracion original del metodo, es decir, si en la clase base hemos definido un metodo que es llamado con una serie de parametros, cuando  redifinimos el mismo metodo en la clase extendida debemos declararlo con los mismo parametros que en su clase base. Pero como ya he comentado en PHP no es nuestro problema ya que no es un lenguaje fuertemente tipado.

En algunos casos hemos redifinido un metodo pero a su vez nos queremos beneficiar de las acciones que realiza el metodo de la clase base, por lo que nos seria util el poder llamarlo desde la clase extendida, esto no es un problema y lo vamos a comprobar en el siguiente ejemplo :
  1.  <?php
  2. /*
  3. Para la realizacion de este ejemplo pondremos en practica todo
  4. lo que hemos visto en esta serie de capitulos sobre la programacion
  5. orientada a objetos.
  6. */
  7. class classCesta{
  8.   /*
  9.   script que sirve para aplicar el patron Singleton
  10.   y asi obtener una instancia unica
  11.   */
  12.   static $_instance;
  13.   private function __construct(){}
  14.   public static function create()
  15.   {
  16.     if (!self::$_instance instanceof self)
  17.       self::$_instance=new self();
  18.     return self::$_instance;
  19.   }
  20.   /* fin patron Singleton */

  21.   protected $articulos=array();
  22.  
  23.   public function calculo()
  24.   {
  25.     $total = 0;
  26.     if (count($this->articulos))
  27.     {
  28.       reset($this->articulos);
  29.       while($tupla = each($this->articulos))
  30.       {
  31.        $total = $total $tupla[1]['prv'];
  32.       }
  33.     }
  34.     return $total;
  35.   }
  36.   public function addArticulo($articulo='')
  37.   {
  38.     if ($articulo!='')
  39.       $this->articulos[$articulo[id]] = $articulo;
  40.   }
  41. }
  42. ?>
Una vez que tenemos el codigo de nuestra clase base el siguiente paso es crear su clase extendida, con el objetivo de redifinir el metodo "calculo", para apliar su funcionalidad con respecto al metodo de la clase ancestra. El codigo de la clase extendida seria el siguiente :
  1. <?php
  2. class classFactura extends classCesta
  3. {
  4.   /*
  5.   Patron Singleton aplicado a clases extendidas
  6.   */
  7.   static protected $_instance;
  8.   static public  function create()
  9.   {
  10.     if (get_parent_class() &&  get_parent_class()!=get_class())
  11.     {
  12.     parent::create();
  13.     $varsParent = get_object_vars(parent::$_instance);
  14.     $padre=parent::$_instance;
  15.     if (!(self::$_instance instanceof self))
  16.       self::$_instance=new self();
  17.     while (is_array($varsParent) &&  $tupla = each ( $varsParent ) )
  18.       self::$_instance->$tupla[0] = &$padre->$tupla[0];
  19.     }
  20.     else //de la comprobacion si es una clase extendida
  21.     if (!(self::$_instance instanceof self))//el objeto no ha sido creado
  22.       self::$_instance=new self();
  23.  
  24.     return self::$_instance;
  25.   }
  26.   /* fin patron Sigleton */

  27.   protected $iva = 16;

  28.   /*
  29.   Aqui es don redefino el metodo "calculo" de la clase base y
  30.   su vez llamo el de la clase base beneficiarme de sus acciones
  31.   */
  32.   public function calculo()
  33.   {
  34.     //instruccion para llamar al metodo de la clase base
  35.     $total = parent::calculo();
  36.     $total = $total ($total*($this->iva/100));
  37.     return $total;
  38.   }
  39. }
  40. ?>
Ya tenemos el codigo de la clase extendida, comentar tan solo que el ejemplo consiste en una minima simulacion de un proceso de compra, donde tenemos la clase "classCesta" que se encarga de poner productos en la cesta y calcular su base imponible, y la clase "classFactura" cuya funcion consiste en extender "classCesta" y  la utilizamos para calcular el precio final aplicando el IVA.

A continuacion finalizare el ejemplo con lo que seria el codigo de como instanciar y utlizar las clases que hemos creado. El codigo seria el siguiente :
  1.  <?php
  2. /*
  3. Suponemos que cada clase la hemos guardado en archivos diferentes
  4. solo tenemos que incluir cada archivo en nuestro codigo.
  5. */
  6. require_once 'classCesta.php';
  7. require_once 'classFactura.php';

  8. //para nuestro ejemplo simulamos una tabla articulos
  9. $artEjemplo = array(
  10. 0=>array('id'=>5,'prv'=>150,'nombre'=>'zapatos pepe'),
  11. 1=>array('id'=>15,'prv'=>50,'nombre'=>'camisa juan'),
  12. 2=>array('id'=>2,'prv'=>5,'nombre'=>'gorra anton')
  13. );

  14. //creamos los objetos, hay que tener en cuenta que al haber aplicado
  15. //el patron Singleton la forma de crear el objeto difiere de la
  16. //manera habitual en PHP, existe un articulo en el portal que
  17. //habla sobre este tema
  18. $cesta = classCesta::create();
  19. $factura = classFactura::create();

  20. //añadimos articulos a la cesta
  21. $cesta->addArticulo($artEjemplo[0]);
  22. $cesta->addArticulo($artEjemplo[2]);

  23. //Llamamos a los metodos de calculo para comprobar que la
  24. //redifinicion del metodo "calculo" se ha realizado con exito.
  25. echo 'Base imponible : '.$cesta->calculo().'<br/>';
  26. echo 'Total factura : '.$factura->calculo().'<br/>';
  27. ?>
Comentarios finales.

Solo comentar una peculiaridad de este ultimo ejemplo, ya que he utilizado una forma personalizada para la creacion de objetos, esto ha sido asi porque he querido aplicar el patron Singleton para poder crear un unico acceso global a una determinada clase, esto quiere decir que todos los objetos que creemos de una misma clase compartiran la misma instancia.

Para aquellos que le interese profundizar un poco mas sobre este tema les dejo el enlace a un articulo publicado en este mismo portal dedicado a la implementacion del patron Singleton.

Patron Singleton para clases extendidas en PHP
Y hasta aqui este capitulo dedicado a la herencia de clases dentro dela programacion orientada a objetos en PHP, espero que os haya resultado de interes y os invito a que dejeis vuestro comentario para saber vuestra opinion.

Gracias por todos y nos vemos en futuras publicaciones.

Ultimas noticias

Crea tu propio framework en javascript

Recopilacion de articulos donde mostrare paso a paso como podemos crear nuestro propio framework en javascript, totalmente funcional y listo para ser utilizado en nuestros futuros proyectos.

Para mas informacion :

Tutorial para crear tu propio FrameWork en JavaSript

Más información
13/12/2013 11:42:57

Como crear una DLL en delphi?

En esta serie de 2 capitulos veremos como crear y utilizar una DLL en Delphi.

Abajo os dejo los enlaces a estos 2 capitulos que componen este mini tutorial, espero que sea de vuestro agrado :

Capitulo 1 : Creacion y utilizacion de una DLL

Capitulo 2 : Creacion de un formulario dinamico utilizando una DLL
Más información
19/09/2013 17:35:59

Ya puedes publicar tu opinion

A partir de ahora ya puedes comentar todas las publicaciones que encuentres en el portal.

Podras opinar tanto si algo te gusta como si no, o si crees que es conveniente completar alguna publicacion, ya que la encuentras incompleta o erronea.

O simplemente por si nos quieres felictar por algo bien hecho :-).

Valoraremos cualquier critica que nos puedas hacer.
Más información
20/05/2013 15:30:10

Tutorial PHP5

Fundamentos de la programacion orientada a objetos
Un interesante tutorial repartido en una serie de capitulos donde se tratan los conocimientos basicos de la programacion orientada a objetos (POO) en PHP5.

Para mayor informacion siga el siguiente enlace :

Tutorial POO en PHP

Más información
04/09/2013 15:44:29
0