viernes, 7 de diciembre de 2012

PHP: Objetos III (Encapsulamiento)

Hola, en el siguiente post abordaremos lo que es el Encapsulamiento en php. Aunque este lenguaje de programación no es muy estricto en cuanto a POO, se pueden emular la mayoría de cosas que son necesarias en Objetos, en este caso Encapsulamiento. Para comenzar es bueno tener en cuenta la ocultación de información(encapsulamiento). Muchos dicen que PHP rompe el encapsulamiento debido a que nos permite acceder a cualquier atributo de una clase directamente, pero en si hay una forma de hacer que no se pueda y así generar el encapsulamiento. Para ello tenemos el concepto de visibilidad en php.

El concepto de visibilidad nos dice que hay tres palabras claves/reservadas: public, protected y private que anteponiendolas a cualquier método o atributo/propiedad se podrán modificar o implementar su visibilidad, haciendo posible el encapsulamiento.

Public: Se podrá acceder a ella de cualquier forma, directamente o por métodos de la misma o de otras clases. Ejemplo:

 1 class Persona{
 2     public $nombre;
 3     public $apellido;
 4     public $edad; // Es public por lo que se accede desde 
 5     cualquier parte
 6     public function __construct($nom, $ape, $e){
 7          $this->nombre = $nom;
 8          $this->apellido= $ape;
 9          $this->edad = $e;
10     }
11     public function imprimir(){
12         return $this->edad;
13     }
14 }
15 $persona = new Persona('Pepito','Perez',24);
16  echo $persona->edad;
17  echo $persona->imprimir();

Como vemos es la misma clase persona que se viene trabajando. Creamos el objeto y hacemos echo a la edad directamente, lo que nos imprimira un 24, despues por medio del metodo imprimir() tambien nos pondra en pantalla el mismo dato, teniendo en cuenta el return en la linea 12.

Protected: Si cambiamos el public por el protected y dejamos lo demas igual, nos saldra un fatal error, ya que con protected no nos dejara acceder a la propiedad a menos que sea por métodos de la misma clase, herencia o con el parent.

 1 class Persona{
 2     public $nombre;
 3     public $apellido;
 4     protected $edad; 
 5     public function __construct($nom, $ape, $e){
 6           $this->nombre = $nom;
 7           $this->apellido= $ape;
 8           $this->edad = $e;
 9     }
10     public function imprimir(){
11         return $this->edad;
12     }
13 }
14 $persona = new Persona('Pepito','Perez',24);
15 echo $persona->edad;
16 echo $persona->imprimir();

Si comentamos la linea donde imprimimos directamente la propiedad, nos imprimira el resultado del metodo imprimir().

 1 //echo $persona->edad;
 2 echo $persona->imprimir();

Private: Al poner la propiedad edad en private solo nos dejara acceder desde la misma clase, entonces si hacemos el ejercicio anterior
 1 class Persona{
 2     public $nombre;
 3     public $apellido;
 4     private $edad; 
 5     public function __construct($nom, $ape, $e){
 6           $this->nombre = $nom;
 7           $this->apellido= $ape;
 8           $this->edad = $e;
 9     }
10     public function imprimir(){
11         return $this->edad;
12     }
13 }
14 class trabajo extends Persona{
15     public $trabajos;
16     public $pruebas;
17     public function trabajar($job){
18         $this->trabajos = $job;
19     }
20     public function imprimir(){
21         return 'Mi nombre es '.$this->nombre.' '.$this->
           apellido.' y tengo '.$this->edad.' Años y trabajo 
           en  '.$this->trabajos;
22     }  
23  }
24 $persona = new Persona('Pepito','Perez',24);
25 echo $persona->imprimir();

Si corremos php con el siguiente código, no nos dejara acceder a la propiedad edad de la clase Persona desde trabajo porque es privada, si fuera protected si nos dejaria pero solo por metodos o parent.

Esto es encapsulamiento en PHP.



PHP: Objetos II (Herencia)

Hola, este es el siguiente post de objetos, aqui mostrare lo que es Herencia, una parte fundamental de la POO en php. Entonces suponiendo que leimos el primer post, tenemos una clase persona con dos metodos, el cual uno es el constructor y otro es el metodo imprimir(), entonces dejemos la clase hasta ahi, podemos borras la instancia del objeto, que hicimos posteriormente.

Como lo dice Wikipedia, "Mecanismo por el cual una clase se deriva de otra de manera que extiende su funcionalidad. La clase de la que se hereda se suele denominar clase baseclase padresuperclaseclase ancestro (el vocabulario que se utiliza suele depender en gran medida del lenguaje de programación).". Eso quiere decir es que una clase padre, tiene n metodos, los cuales puede heredar una clase hija para su correcto funcionamiento.

Ya sabemos que es herencia, pero no podemos verlo en forma porque para ello necesitaríamos otro objeto que accediera a nuestro objeto persona. Pues entonces vamos a construir uno, y de una vez veremos el ejemplo de herencia.
Como vemos en el anterior codigo, es una clase de nombre trabajo y despues viene lo importante, la palabra reservada de PHP, extends, nos dice que esa clase heredara de otra, en este caso persona, en ellas hay un atributo llamado $trabajos y dos metodos publicos, los cuales son trabajar() e imprimir(). Con esto ya podemos acceder desde trabajo a Persona, y lo hacemos de la siguiente manera.

01 class trabajo extends Persona{
02     private $trabajos;
03     public function trabajar($job){
04  $this->trabajos = $job;
05     }
06     public function imprimir(){
07   return 'Mi nombre es '.$this->nombre.' '.$this->
08  apellido.' tengo '.
09  $this->edad.' años y trabajo en '.$this->trabajos;
10     }  
11 }

Hemos agregado tres lineas de codigo mas, los cuales son los de instanciar una clase o creando un objeto, este objeto hereda de Persona el contructor y por ello enviamos 3 datos, despues invocamos un metodo que viene de la clase trabajo llamado trabajar() que nos recibe el trabajo que estamos haciendo, y por ultimo 

hacemos un echo al metodo imprimir() de la clase trabajo. Aqui hay dos cosas para ver, para ello veremos todo el codigo que llevamos
01 class Persona{
02     public $nombre;
03     public $apellido;
04     public $edad;
05     public function __construct($nom, $ape, $e){
06         $this->nombre = $nom;
07  $this->apellido= $ape;
08  $this->edad = $e;
09     }
10     public function imprimir(){
11         return 'Mi nombre es '.$this->nombre.' '.$this->
12         apellido.' y tengo '.
13         $this->edad.' Años';
14     }
15 } 
16 class trabajo extends Persona{
17     private $trabajos;
18     public function trabajar($job){
19          $this->trabajos = $job;
20     }
21     public function imprimir(){
22          return 'Mi nombre es '.$this->nombre.' '.$this->
23          apellido.' tengo '.
24          $this->edad.' años y trabajo en '.$this->trabajos;
25     }  
26 }
27 $trabajo = new trabajo('Pepito','Perez','24');
28 $trabajo->trabajar('informatica');
29 echo $trabajo->imprimir(); 
Vemos facilmente las dos clases, una heredando de otra y ademas que tienen cada una un metodo con el mismo nombre, pues cuando llamo un metodo igual que el metodo de una clase base, esto se llama redefinir metodos, que no es mas que sobreescribir el metodo en la clase que hereda, lo siguiente es que PHP ingresa al imprimir redefinido, es decir a la clase que hereda, por lo que en nuestro caso imprimira la parte "y trabajo en .....", en caso de que quisieramos acceder a un metodo de la clase base, lo haremos via parent de la siguiente manera:
01 public function imprimir(){
02     $pruebas = parent::imprimir(); // La variable $pruebas la declare en trabajo
03     return $pruebas;
04 }

Como vemos asignamos a una variable el valor de parent que significa buscar en la clase base, seguido de "::", que trabajaria similar al '->' y por ultimo el metodo que queramos invocar. Hacemos el return de la variable que contiene la respuesta y listo, nos imprimira todo lo que hay en nuestro metodo imprimir de la clase Persona, que en este caso solo nos imprimira hasta Años.


Hasta aqui va este post que esta como largo, en otro explicare lo que es encapsulamiento y polimorfismo.