Interfaces en la programación orientada a objetos

Pues hoy vamos a hablar de las interfaces en la programación orientada objetos. Si estas siguiendo la serie de artículos dedicados a aprender sobre programación POO ya habrás visto como crear objetos, clases, clases abstractas y habrás aprendido sobre métodos, propiedades y su visibilidad, en fin… un conjunto de conceptos teóricos que te estarán dando una nueva perspectiva sobre la tecnología, o eso espero vamos…

Y hoy precisamente toca eso, ver las interfaces y cómo y cuando podemos implementarlas así que…vamos a ello!

¿Qué son las interfaces?

Las interfaces vienen a ser como una declaración de funcionalidades obligatorias que tienen que realizar aquellas clases que implementen la interface. A diferencia de como vimos con las clases abstractas, las interfaces no declaran sus métodos nunca, tan solo definen los métodos. Esto es, en una interface aparecerá pues el nombre del método junto con su visibilidad y la definición de argumentos para jamás pueden describir código, entonces sería una clase abstracta.

Otra diferencia respecto al uso entre interfaces y clases abstractas es que una clase cualquiera puede implementar tantas interfaces como le de la gana pero únicamente puede heredar de una clase, ya sea abstracta o no, al menos en PHP y esto es lo que se conoce como herencia simple.

Cuando veamos el artículo de herencia de objetos veremos las diferencias entre herencia múltiple y herencia simple.

Volviendo al tema de las interfaces tenemos que saber que en el sentido estricto de la definición, una interface es como si fuera una hoja de ordenes diciéndonos qué es lo que hay que hacer pero no como. Una interface estará formada pues únicamente por constantes y la definición de sus métodos, que jamás serán abstractos (sino hablaríamos de clase abstracta)

Una interface es el claro ejemplo de la abstracción.

https://gist.github.com/gorkamu/7fb35daa09e7562ed31e39c8b1d7968a.js

Al implementar una interface en una clase se nos está obligando a implementar siempre todos los métodos que defina, nos guste o no, aunque existe una excepción que no se suele utilizar y es que si una clase abstracta implementa una interface, esta no esta obligada a implementar los métodos de la interface.

Para hacer uso de una interface tendremos que hacerlo mediante el operador implements junto al nombre de la clase, tal y como hemos visto cuando heredamos (o extendemos) de otra clase. Pero que esto no te despiste porque no es exclusivo que las interfaces solo se utilicen con implements y las clases con extends ya que las interfaces también pueden heredar de otras interfaces.

Hemos dicho que una interface está formada por la definición de sus métodos y por constantes, pues bien estas constantes funcional igual que si fueran constantes de clases pero se diferencian en que estas no puede ser sobrescritas por la clase/interface que la herede o de lo contrario nos dará un error.

Las interfaces suponen junto con la determinación de tipos de una buena forma de asegurarse de que un determinado objeto contiene ciertos métodos y para ello el operador instanceof() juega un papel muy importante. Checkea el enlace anda 😉

Pues nada amigüitos, se que el tema es complejo debido a que estamos tocando temas bastante abstractos así que si tienes alguna pregunta no dudes en dejármela en los comentarios o en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Clases abstractas en la programación orientada a objetos

Echa la vista atrás y mira cuantas cosas has tenido que aprender si has seguido esta serie de artículos. Si te has leído cada uno ya serás capaz de crear clases y objetos, inicializar y destruir valores con sus constructores y destructores respectivamente, habrás aprendido los diferentes tipos de datos que tenemos y su visibilidad entre otras cosas. Pues bien, en esta entrada vamos a ver qué son las clases abstractas en la programación orientada a objetos.

¿Qué son las clases abstractas?

Una clase abstracta es aquella que no se puede instancias. Si una clase posee un método abstracto por narices ha de ser abstracta también. Por lo general utilizamos las clases abstractas para definir comportamientos comunes o generales pero sin especificar como lo hacen. Es habitual que los métodos de estas clases abstractas no tengan cuerpo de declaración, es decir, solo tienen la definición del método, el nombre y la visibilidad vaya.

¿Pero esto como puede ser? Pues muy sencillo, imagínate a las clases abstractas como simples guiones o conjunto de TODOs para otras clases. En ellas se indican que tareas hay que hacer pero no cómo hacerlas y serán las clases hijas que hereden de las clases abstractas las que decidan cómo hacer esas tareas.

Por ejemplo, mi padre decide que su coche esta muy sucio y me ordena que debo lavarlo, pero no me indica como. Puedo llevarlo a un túnel de lavado, puedo darle con la manguera o puedo coger un barreño de agua, jabón y un cepillo y limpiarlo a mano, uuuff… que pereza…

Pues en este ejemplo mi padre sería la clase abstracta y sus ordenes los métodos abstractos. Cómo decida implementar yo sus ordenes (soy la clase hija) es problema mio.

Pero no solo sirven para definir comportamientos comunes, también sirven para asignar diferentes características y propiedades comunes a las clases hijas.

Vuelve a pensar en mi padre, una característica que heredaré por ser su hijo es su apellido y su tendencia a ser morenos de pelo, aquí ya entramos en genética, pero tal vez lo que no herede son sus gustos musicales, mientras que él escucha a Sabina yo puedo deleitarme con ACDC, por ejemplo…

Tan solo aquellas características y propiedades comunes que definen a un conjunto de clases jerárquicas deberán de ser heredadas, no así las propiedades exclusivas de una única clase. ¿Se entiende no?

Pues bien, con este tipo de clases hay ciertas reglas, características o normas que tenemos que tener en cuenta:

  • Si se definen métodos abstractos en una clase abstracta, todas las clases que hereden de ella han de implementar todos esos métodos.
  • Las clases abstractas si que pueden heredar de otras clases y no tienen porque ser estas abstractas también.
  • El número y tipo de datos de los argumentos de una clase abstracta han de respetarse siempre en las clases hijas.
  • Si una clases esta formada solo por métodos abstractos y constantes entonces es una interface.

En otros lenguajes de programación y no solo en PHP, las clases abstractas están muy relacionadas con el polimorfismo, pero vamos a ver qué es el polimorfismo porque tiene un nombre muy chulo pero puede liar un poquillo…

Cómo utilizar las clases abstractas con el polimorfismo

Agárrate bien los machos porque el polimorfismo junto con la encapsulación y la herencia son las tres patas fundamentales de la programación orientada a objetos, bueno y los objetos claro.

Tal y como sugiere su nombre, el polimorfismo indica muchas formas y en programación esto se puede referir a diferentes comportamientos en función del contexto en el que se este ejecutando la clase.

Pero esto es bastante abstracto, mejor si lo vemos con un ejemplo y para ello vamos a hacer una jerarquía de clases.
https://gist.github.com/gorkamu/d312262a1d38caf4b0da251a31ec19cf.js
Tal y como ves en el ejemplo, he creado cuatro clases:

  • Una clase abstracta que representa el concepto de animal con el método moverse().
  • Una clase Gorrino que hereda de la clase Animal y que implementa el método moverse().
  • Una clase Pajarico que hereda de la clase Animal y que implementa el método moverse().
  • Una clase Acción que tiene un método andar() al que se le pasa un objeto del tipo Animal y ejecuta el método moverse().

Pues bien, hemos metido un animal de cada clase en un array y lo recorremos. Cada uno de los animales se lo pasamos a la acción para que se mueva y sus resultados son los siguientes:

// El gorrino corre
// El pajarico vuela

Vale y a lo mejor te estés preguntando por el polimorfismo y dónde se encuentra en este script. Pues se encuentra en nada mas y nada menos que en la definición del método anda() de la clase Accion. Hemos dicho que espera que le pasemos un argumento del tipo Animal y el método únicamente comprobará que lo que le pasemos herede de esa clase y le dará igual si se trata de un Gorrino o de un Pajarico.

Pues eso es el polimorfismo y ese es el uso que podemos hacer de las clases abstractas. Bueno no es el unico obviamente pero si el mas fácil de ver y explicar 😛

Si después de esto y a medida que programes eres capaz de abstraer tus programas significará que has entendido a la perfección el problema que estas tratando de resolver por lo que enhorabuena aunque no te agobies que se necesita practica y a veces es mejor dar una solución concreta que lucirte haciendo un programa to guapo pero alargando los tiempos de entrega 😉

Se que el tema es bastante difícil de ver y entender si es la primera vez que te encuentras con ello así que si necesitas mas explicaciones o ejemplos por favor pídemelos en los comentarios o en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Objetos en la programación orientada a objetos

Ya hemos visto en artículos anteriores que son los objetos en la programación orientada a objetos pero en este artículo quiero entrar en detalle con una definición bastante aproximada de qué es un objeto y ver diferentes acciones que podemos hacer con ellos como la clonación o la comparación entre ellos, así que… vamos allá.

¿Qué son los objetos en la programación orientada a objetos?

Pues bueno, si eres nuevo y llegas a este tipo de programación lo primero que pensarás es que deben de ser algo importante dentro de este paradigma y así es ya que dentro de la POO son el pilar fundamental y los utilizamos para representar objetos cotidianos de la vida real. Pero antes de entrar mas en el barro vamos a ver qué es lo que dice la wikipedia

En el paradigma de programación orientada a objetos (POO, o bien OOP en inglés), un objeto es una unidad dentro de un programa de computadora que consta de un estado y de un comportamiento, que a su vez constan respectivamente de datos almacenados y de tareas realizables durante el tiempo de ejecución. Un objeto puede ser creado instanciando una clase, como ocurre en la programación orientada a objetos, o mediante escritura directa de código y la replicación otros objetos, como ocurre en la programación basada en prototipos.

Así es, imagínate a un objeto como una estructura no como un valor. Una estructura como un conjunto de valores y de posibles acciones que puede realizar encapsuladas en una única unidad. Para que lo visualices piensa en el número 5. Imagínate que por el hecho de ser un número contiene por si mismo su símbolo, positivo en este caso, y puede sumarse una unidad y restarse una unidad.

Por lo cual el objeto del número que hemos descrito sería tal que así:
https://gist.github.com/gorkamu/970503dd8b0398a5a016d1005501c9b6.js

Lo interesante de los objetos es que cuando los utilizamos en funciones y los pasamos como argumento, no estamos pasando su valor como si se tratase de un tipo de dato como un integer por ejemplo. Un objeto no es un valor. Al pasarlos a una función como argumento estamos pasando su referencia.

Si recuerdas post anteriores, pasar un argumento por referencia significa que lo que modifiquemos dentro de la función se verá afectado fuera de la función también y esto es así porque la referencia es el identificador que indica donde se encuentra ese valor u objeto en memoria. No se hace una copia vaya…

Con los objetos todos son referencias, cuando los pasamos a una función o los devolvemos o se asigna a otra variable, todas las distintas variables guardan una copia de ese identificador que apunta al mismo objeto.

Pero… ¿y qué cosas podemos hacer con los objetos?

Comparación de objetos

Si tenemos dos objetos, podemos evaluar que estos sean iguales o no. Cuando comparamos dos instancias, se realiza una comparación de bajo nivel mirando que todos los valores y atributos sean iguales y que pertenezcan a la misma clase. Podemos realizar dos tipos de comparaciones utilizando diferentes operadores:

  • Operador de comparación: se comparan de forma sencilla las variables y que ambas instancias pertenezca a la misma clase. Para ello utilizamos el operador doble igual (==)
  • Operador de identidad: dos objetos son iguales si sus variables son idénticas sí y sólo sí hacen referencia a la misma instancia de la misma clase. . Para ello utilizamos el operador triple igual (===)
Offtopic:

En Java tenemos los métodos mágicos __equals(),__compareTo() y __compare() para comparar objetos. Aquí mas información

https://gist.github.com/gorkamu/a8615b0270aa92ebe67e3c85a3d9b098.js
Clonación de objetos

Otra acción que podemos hacer con ellos es clonarlos. A veces no nos interesa hacer una copia de un objeto realizando una replicación completa de sus propiedades sino que nos interesa hacer una replica que genere una nueva instancia de ese primer objeto y aquí es donde entra la clonación.

Si queremos hacerlo tenemos que utilizar la palabra reservada clone que internamente hace una llamada al método mágico __clone() del objeto. Si en lugar de utilizar la palabra reservada intentas hacer una llamada al método mágico no te va a dejar realizarlo.
https://gist.github.com/gorkamu/bc27596742d258345e5a37ada0a64a40.js

Serialización de objetos

Te estarás preguntando que qué coño es la serialización ¿no? Pues no es otra cosa que el proceso de representar mediante un string, texto vamos, un objeto. Cuando serializamos uno de ellos lo que pasa es que obtenemos en formato texto el nombre de la clase junto con los valores de ese objeto.

Podemos llevarlo a cabo mediante la función serialize() que tal y como indica su documentación genera una representación almacenable de un valor que no pierde ni su tipo ni su estructura.

Por otro lado, si ya tenemos en un string la representación de un objeto y queremos volver a convertir esa representación a objeto podemos hacerlo mediante la función unserialize() que realiza el proceso contrario a serialize()

Todo este proceso de serializar y deserializar un objeto forma parte del sistema de sesiones de php. Cuando registramos un objeto en la sesión este se serializa automáticamente y automáticamente también se deserializa para cada petición.
https://gist.github.com/gorkamu/ff9fe51208d71a9da53eff56b41703ce.js

Iteración de objetos

La iteración de objetos es el proceso que permite recorrer e iterar cada una de las propiedades de un objeto. Imagina que tienes el objeto de una clase y quieres saber que valores tienen sus propiedades, podrías hacerlo con la función serialize() claro pero no sería una buena practica, lo haríamos a través de un bucle foreach, aunque únicamente devolverá todas las propiedades public si no lo implementamos en una función dentro de la clase.

Ejemplo:
https://gist.github.com/gorkamu/430cc2f1f23246dd146a707dd92628e5.js

Como se ve en el script, el bucle que se encuentra fuera de la clase únicamente tendrá acceso a las propiedades públicas y sin embargo mediante la función iterar() podemos acceder a todas las propiedades, públicas, protegidas y privadas.

También podemos hacer uso de interfaces para realizar este propósito e implementar la interfaz Iterator. Esta interfaz nos da la herramientas para poder decidir y definir como ha de iterarse un objeto y que valores serán utilizados.
https://gist.github.com/gorkamu/40c297d225121156ee65b9c4afc7a843.js

Pues nada chachos, con este post hemos definido qué son los objetos en la programación orientada a objetos y qué acciones podemos hacer con y sobre ellos. Se que el tema es duro y espesito así que si tienes alguna pregunta no dudes en hacérmela a través de los comentarios o poniéndome un tweet mediante el siguiente banner y te prometo que te responderé lo antes posible.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

 

Hala a mamarla!

Tipos de datos y argumentos en la programación orientada a objetos

Si estás siguiendo esta serie de artículos relacionados con la programación orientada a objetos ya tendrás unos datos mínimos necesarios para empezar a crear tus pequeños scripts. Pues bien, hoy vamos a explicar qué tipos de datos podemos utilizar en nuestros programas y cómo pasárselos a nuestras funciones o métodos, lo que se conoce como paso de argumentos vaya…

¿Qué son y cuántos tipos de datos existen?

Gran pregunta. Ya sabes lo que es una variable, pero si por un casual has caído en el post sin haber leído los artículos anteriores (te recomiendo que te los leas) imagina que una variable es como una caja vacía. En función del tamaño de la caja vas a poder guardar diferentes cosas en ella, desde un boli, a una pelota, una televisión o un conjunto de otras cajas mas pequeñitas.

Pues una variable es eso, una caja en la que guardar datos y los objetos que he dicho antes son los diferentes tipos de datos. Si por ejemplo intentas guardar una televisión en una caja que está pensada para guardar bolígrafos vas a comprobar que es imposible. Pues eso también pasa en la programación.

Internamente las variables son espacios de memoria reservada y para optimizar la memoria siempre se reserva el espacio que necesita el tipo de dato que contendrá la variable, es decir, si quiero guardar la tele en mi armario voy a reservar una caja que tenga el tamaño de la televisión que me interesa almacenar.

En los lenguajes de programación fuertemente tipados esto se respeta to the limit, con ellos no puedes guardar un tipo de dato diferente al tipo de dato con el que has declarado la variable. C y C++ es un lenguaje de programación con un tipado fuerte y me gusta especialmente ya que aunque el ritmo de programación sea mas lento que en comparación con otros lenguajes te aseguras que tu programa es robusto ya que por ejemplo te quitas la preocupación de que se pueda guardar una televisión en una cajita de bolígrafos.

Sin embargo también existen los lenguajes con un tipado débil, como PHP hasta su versión 7 y… y… Estos lenguajes son mas laxos a la hora de permitir guardar datos diferentes en las variables, de hecho esto puede ser una ventaja a la hora de programar pero también te exige estar mas atento a medida que escribes para no cagarla.

Pues bien, en PHP tenemos los siguientes tipos de datos:

Tipo de dato Descripción Valores Ejemplo
Boolean Es el tipo mas simple de todos y su valor representa una verdad. true/false $var = true;
Integer Es un número entero y puede especificarse con notación decimal (base 10), hexadecimal (base 16), octal (base 8) o binaria (base 2), opcionalmente precedidos por un signo (- o +). Números enteros $var = 1;
Floats Es un número decimal o número de punto flotante. Números decimales $a = 1.234;
$b = 1.2e3;
$c = 7E-10;
Strings Texto o cadena de caracteres. Texto $var = ‘Gorkamu’;
Arrays Estructura que puede guardar un conjunto de otros datos. En realidad es un mapa ordenado en el existen nodos con una clave y un valor. Conjunto de valores $var = [1 => ‘Hola’, 2 => ‘Gorka’];
Object Un objeto de una clase que se crea con la palabra reservada new Objeto $var = new Gorkamu();
NULL Sin valor null $var = null;
Atención

Los arrays son complejos, por favor revisa este documento para saber mas de ellos.

Mantén esta tablita a mano que a medida que aprendes y vas adquiriendo soltura con los tipos de datos te será muy útil.

Ya has aprendido a crear variables con diferentes tipos de datos, ahora toca pasarle esos valores a las funciones y métodos que programes.

Pasando argumentos a funciones y métodos

Bien, en este artículo anterior habrás aprendido que son los métodos y/o funciones, en el fondo es lo mismo y lo mas importante, habrás aprendido a crearlos. Pues ahora vamos a ver cómo pasarle datos a esas funciones.

Si te cuesta un poco visualizarlo imagínate una cadena humana en la que el primero de la fila tiene un bol lleno de palomitas y tiene que pasárselo al último que le ha pedido unas pocas. Siguiendo la cadena, el bol de palomitas ira pasando de persona en persona hasta llegar al último. Pues cada persona es una función o método que recibe algo (el bol de palomitas) y devuelve algo (el bol de palomitas)

Es posible que algún miembro de la fila manipule el bol de palomitas, tal vez alguno se lo pasará al siguiente sin hacerle nada, otro cojera un puñado, otro le echará un poquito mas de sal y si por desgracia en la cadena humana tenemos a un gordo fanegas es muy posible que se coma el bol de palomitas y no llegue nada.

¿Ha quedado claro no? xD

Pues eso, en PHP podemos pasar tantos valores, de ahora en adelante argumentos, como nos de la gana. Tendremos que separarlos por comas y existen tres formas diferentes de pasar los argumentos a las funciones.

Paso de argumentos por valor

Es el paso de argumentos por defecto. Cuando pasas un argumento a la función y el valor de este argumento cambia dentro de la función, su valor original, el de fuera de la función no se verá afectado.
https://gist.github.com/gorkamu/ff4a0be97e0c2f654d1eaf4d3a765c52.js

Paso de argumentos por referencia

Cuando pasas un argumento por referencia, si cambias o modificas su valor dentro de la función su valor original, fuera de la función, también se verá afectado. Para indicar que un argumento se pasa por valor lo tenemos que hacer indicándolo con el ampersand (&)
https://gist.github.com/gorkamu/ab2daeca875374646377f0283e52852c.js

Puede ser útil para modificar valores en funciones sin tener que indicar un return.

Paso de argumentos predeterminados

Si definimos una función que acepte argumentos es posible que nos interese que alguno de ellos tenga un valor por defecto. Si a la hora de llamar a esa función no le pasamos valor para ese argumento, el argumento tomará el valor por defecto dentro la función. Por el contrario, si a la función le indicamos un valor para argumento, ese argumento tomará dentro de la función el valor que hemos pasado.
https://gist.github.com/gorkamu/5b460caf1c7e957d98ca70de8df1d0d1.js
Otra cosa interesante que podemos hacer respecto a los argumentos de una función es definir una lista de longitud variable, esto es, en la declaración de la función no tenemos porque indicar uno por uno los argumentos que vamos a pasar. Si utilizamos el token “…” antes del argumento, PHP ya sabrá que se trata de una lista variable aunque eso si, todos los argumentos pasados han de ser del mismo tipo.
https://gist.github.com/gorkamu/2686a295c7209d525843af22e1740bfa.js
Pues nada chavales, a practicar y a realizar un huevo de ejercicios para que estos son conceptos se posen en tu cabecita y ya sabes, si tienes dudas dejame un comentario y te la resolveré o ponme un tweet a través del siguiente banner 😉

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Constructores y destructores en la programación orientada a objetos

Que pasa churritas!

En artículos anteriores vimos los conceptos básicos de la programación orientada a objetos junto a la definición ampliada de las propiedades y constantes de clases. Si te has leído estos artículos ya deberías saber cómo hacer una clase y cómo utilizar la visibilidad de sus miembros para acceder a sus métodos y propiedades.

Pues bien, en este artículo vamos a hablar de los constructores y los destructores, esos mecanismos de construcción y destrucción de objetos que internamente sirven para reservar y liberar espacio en la memoria de nuestra máquina. Comenzamos.

Constructores y destructores

¿Tienen un nombre importante verdad? Constructores y destructores, wow, parecen métodos importantes y no son para menos porque son super importantes. Cuando creamos un objeto internamente estamos reservando un espacio de memoria que después utilizaremos asignando valores y leyendo de ella aunque este proceso sea transparente al programador y al usuario. El propio núcleo se encarga de hacerlo por lo que si decidimos trabajar con un lenguaje de programación de alto nivel como PHP es una preocupación menos que tener en cuenta.

Para definir el constructor de una clase utilizaremos el método mágico __construct() y tradicionalmente lo utilizaremos para inicializar ciertos valores necesarios de nuestra clase. El método constructor de una clase es el primer método que se ejecuta cuando instanciamos un nuevo objeto. Es el proceso que se va a encargar de crearnos el objeto, ¿bastante obvio según su nombre no?

Ahora bien, has de saber que como método mágico que es no es necesario ni obligatorio que lo declaremos en nuestras clases. Si volvemos al ejemplo de la clase de Gorkamu.class.php no verás en ella ningún constructor y esto es porque se utiliza el constructor por defecto. El propio núcleo de PHP cuando compile nuestra clase ya va a saber que tiene que llamarlo sin que nosotros tengamos que indicárselo.
https://gist.github.com/gorkamu/7ceba19c9b8521203231cf819cc9dbb5.js
La única razón que tenemos para declarar un método constructor en nuestra clase es para inicializar variables y esto es una buena práctica que tiene que ver con la encapsulación y la visibilidad, me explico. Dónde en ejemplos anteriores habíamos asignado valores directamente en la declaración de las propiedades, lo correcto sería asignar esos valores en el constructor de la clase.

https://gist.github.com/gorkamu/2b6857d5051b81476ba3ad79abe08d58.js

Por otro lado, si nuestra clase hereda de otra, no tenemos porqué definir ningún constructor a no ser que tengamos que hacer algo específico. Cuando nuestras clases estén compiladas, el flujo de ejecución primero ejecutará el método constructor de la clase padre si lo hubiera y sino su constructor por defecto para después hacer una llamada al constructor de la clase hija, ya sea uno declarado o el método por defecto.

Esto es así aquí y en la China.

Aunque si en nuestra clase hija queremos hacer una llamada al constructor de la clase padre tendremos que hacerlo mediante las palabras reservadas parent::__contruct()

La ventaja que tienen los constructores y su sobrescritura es que si al constructor hijo le pasamos mas parámetros (o menos) de los que tiene el constructor padre PHP se callará como una puta y no nos dará ningún error a nivel de E_STRICT.

El método destructor

Por desgracia no me estoy refiriendo al arma letal de la estrella de la muerte. El método destructor es el proceso que utiliza el núcleo de nuestro lenguaje de programación para liberar espacio en memoria. Cuando un objeto queda obsoleto y ya no quedan referencias al objeto se ejecutará este método.

Típicamente los utilizamos para terminar con procesos de nuestro programa, por ejemplo podríamos poner la clausura de una conexión a base de datos aquí o hacer que escriba en un log que la clase ha sido destruida para llevar un control de qué esta pasando. No sé…

https://gist.github.com/gorkamu/1c7df54e7868fdebe398517f893054e1.js

Al igual que con los métodos constructores y la herencia, con los métodos destructores pasa igual ya que si queremos hacer una llamada al método padre tendremos que hacerlo con las palabras reservadas parent::__destruct()

Esto es interesante ya que si ejecutamos el método exit() los destructores serán invocados pero sin embargo hacemos una llamada a exit() dentro de un método destructor muy posiblemente la estaremos cagando ya que estaremos dejando de ejecutar el resto de rutinas de finalización que queden, así que cuidadín.

Las dos últimas cosas que tienes que tener en cuenta con los destructores es que los métodos destructores invocados durante la finalización de un script ya han enviado las cabeceras HTTP, lo veremos mas adelante, así que no nos tenemos que preocupar de ello y por otro lado, si por algún caso vas a lanzar una excepción desde un destructor que sepas que te va a dar un error fatal. No se me ocurre una razón para hacer esto ya que existen otros mecanismos para hacerlo pero oye…

 

Pues nada chachos, ya sabéis como construir y destruir objetos y aunque no los utilicéis por lo menos conocéis los procesos internos que se llevan a cabo. Se que el tema es duro y espeso así que si tienes dudas déjamelas en los comentarios o en twitter a través del siguiente banner 😉

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

POO: Propiedades y constantes de clase

Ya hemos visto en un post anterior los conceptos básicos de la programación orientada a objetos. En el explicábamos lo que es una clase en programación orientada a objetos, de ahora en adelante POO, qué es un objeto, una instancia y cómo crearlas. También conté un poco por encima como clonar objetos y que papel juegan los constructores y los destructores, entre otras cosas.

Pues bien, hoy toca entrar en profundidad en las propiedades y en las constantes de clases.

Propiedades de clases

Ya vimos que una clase es una representación abstracta de un objeto. Todo objeto tiene por su definición ciertas propiedades que almacenaremos en variables. No es exclusivo que sean llamadas propiedades, en algunos contextos podrán ser llamadas atributos o campos de clase, en cualquier caso da igual ya que estamos haciendo referencia a lo mismo.

Si tenemos un objeto televisión, sus propiedades podrían ser la marca de la televisión, sus dimensiones y su tipo. Así pues de una televisión plana de 47 pulgadas de la marca Samsung, plana, 47 pulgadas y Samsung podrían ser las propiedades de la clase televisión. ¿Hasta aquí bien no?

Para definir una propiedad de una clase tenemos que utilizar una de las siguientes palabras reservadas, public, protected y private en función de la visibilidad que queramos dar a esa propiedad. ¿Pero qué coño es la visibilidad?

Visibilidad de propiedades y métodos

La visibilidad de propiedades y métodos hace referencia al tipo de accesibilidad de las propiedades y de los métodos de una clase. La accesibilidad es desde dónde se puede acceder al valor de una propiedad o desde dónde se puede llamar al método de una clase. Tenemos tres tipos de visibilidades:

  • public: una propiedad o un método public puede ser accesible desde donde sea. Si una propiedad es definida mediante la palabra reservada var automáticamente su visibilidad será pública, sin embargo si un método no ha definido visibilidad pasará a ser un método público.
  • protected: una propiedad o método protected solamente será accesible desde la propia clase o desde clases heredadas.
  • private: una propiedad o método private solamente serán accesibles desde la propia clase.

Una cosa interesante a tener en cuenta de la visibilidad entre objetos es que los objetos del mismo tipo pueden acceder a los miembros protected y private entre ellos aunque no pertenezcan a la misma instancia.

Vale, para acceder al miembro de una clase utilizamos el símbolo -> ya sea una propiedad o un método, sin embargo tal y como vimos en el post anterior, para acceder a una propiedad desde dentro de la misma clase tendremos que utilizar la pseudovariable $this. Si recuerdas bien esta pseudovariable es una referencia al objeto invocador, el que esta realizando la acción vamos.

Siempre tendremos que llamar a una propiedad o método mediante la flechita siempre y cuando no se trate de una propiedad o método estático.

Propiedades y métodos estáticos

Una propiedad o método estático significa que puede ser accesible sin tener que instanciar la clase, es decir, sin tener que utilizar la palabra reservada new. Hay que recordar que si un método ha sido definido como estático no podremos utilizar la pseudovariable $this dentro del método ya que nos dará un error.

Con las propiedades estáticas nos pasa lo mismo. Una vez que hemos definido una propiedad como estática si intentamos acceder a ella utilizando $this-> dentro de un método nos dará un error, en su lugar tendremos que utilizar la palabra reservada self:: si la propiedad pertenece a la clase o la palabra reservada parent:: si la propiedad pertenece a una clase padre, cuando realizamos herencia.
https://gist.github.com/gorkamu/73d6db5a544334fa54b13910be3e69a8.js
A partir de la versión 5.3.0 de PHP podemos utilizar los heredocs y los nowdocs en cualquier contexto estático, incluso cuando declaramos propiedades. Por favor, sigue lo enlaces para saber qué son.

Bien, ya hemos pasado la primera parte del post. Hemos terminado de contar lo que son las propiedades de clase y nos vamos a meter con las constantes. ¿Quieres hacer un descansito? Vamos que queda poco… 😛

Constantes de clases

¿Qué te sugiere que algo sea constante? ¿Que no cambia, no? Algo cuyo valor o estado se mantiene igual durante el paso del tiempo ¿no? Pues eso es lo mismo en la programación orientada a objetos.

Siempre y cuando digo siempre es siempre podremos definir una variable como constante dentro de una clase. Al definir una propiedad como constante nos estamos asegurando de que su valor no va a cambiar jamás durante la ejecución del programa pero tenemos que ser conscientes de que tampoco podremos modificar su valor.

Por defecto la visibilidad de una constante es public, es decir, podremos acceder a ella desde cualquier lugar.

Esto viene genial cuando queremos definir literales o cuando queremos evitarnos los números mágicos por ejemplo.

Para definir una constante de clase tendremos que utilizar la palabra reservada const y a diferencia de las propiedades o variables normales, en las constantes no tenemos que utilizar el símbolo del dolar ($) cuando las declaramos. De hecho es típico y una buena práctica escribir las constantes en mayúsculas. Con el siguiente ejemplo lo verás rápido.
https://gist.github.com/gorkamu/7ceba19c9b8521203231cf819cc9dbb5.js
Como ves en el ejemplo podemos acceder a la constante de diferentes formas, ya sea desde un método get, desde la clase instanciada como si fuera una propiedad estática o sin tener que instanciar la clase. Las constantes son super útiles.

 

Pues nada, hasta aquí la parte dedicada a las propiedades y constantes de la programación orientada a objetos y todavía queda mucho mas!

Se que el tema puede ser duro y espesito así que si tienes dudas puedes dejarmelas en los comentarios o hacerlas en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Conceptos básicos de la programación orientada a objetos

En pleno siglo XXI y con una tendencia cada vez mas en aumento del dominio digital en nuestras vidas es imprescindible que todos tengamos unos conocimientos mínimos sobre informática, tecnología y programación. A lo largo de mi vida he conocido a muchas personas que solo sabían encender el ordenador y acceder a sus redes sociales, compartir sus fotos en Instragram y descargar películas desde plataformas de sharing.

Y tal vez eso sea suficiente para ellos pero si ahora mismo desarrollas un trabajo delante de un ordenador deberías tener unos conocimientos técnicos mínimos; y no hablo de conocer el sistema de señales del kernel de nuestro ordenador o saber como gestionar la memoria de tu máquina, tan solo quiero remarcar la importancia de poseer unos conocimientos técnicos en un mundo en el que cada vez dependemos mas de la informática.

Ya se ha demostrado la sana relación que existe entre los niños y la programación en su proceso de aprendizaje maduro. Esto tiene muchísimas ventajas en la formación del cerebro y en su definición de la personalidad. Un niño que aprende programación esta sin saberlo amueblando su cabeza y recibiendo herramientas para pensar de una manera lógica y desarrollando su capacidad para resolver problemas.

Entonces, si un niño es capaz de aprender un lenguaje de programación ¿porque tu no vas a poder aprenderlo?

Otra cosa es si de verdad quieres desarrollar su autosuficiencia tecnológica o si por el contrario quieres seguir dependiendo del friki gordo que juega con los ordenadores toda tu vida. Cuando ese tío ya no este, ¿qué vas a hacer cuando aparezca la temida Blue Screen Of Death en tu ordenador y tu trabajo tenga que ser interrumpido? Por ejemplo…

Por eso y como modo de educación os voy a contar los conceptos de la programación para que a los que os interesa sigáis aprendiendo y para los que no os interesa tanto por lo menos que conozcáis en qué se basa nuestro trabajo y desmentir el mito de que los programadores apretamos un botón y el trabajo ya está hecho.

Por cierto, no somos vagos. Trabajamos con la ley del mínimo esfuerzo pero siempre buscando la manera de optimizar y automatizar procesos de trabajo. 😛

programador

¿Qué es la programación orientada a objetos?

Dentro de la programación existen diferentes paradigmas sobre como afrontar y resolver un problema y estos tipos de paradigma están ligados al desarrollo histórico de la tecnología y de nuestra capacidad para producir mejores máquinas y aumentar la capacidad de cálculo y procesamiento de estas.

Si hacemos una búsqueda rápida veremos que podemos desarrollar haciendo programación funcional, programación imperativa, programación estructural, programación orientada a objetos o las recientes en alcanzar hype programación orientada a eventos y orientada a comportamientos, entre muchas otras…

Pero en este caso vamos a aprender qué es la programación orientada a objetos y para ello la wikipedia nos dice lo siguiente:

La programación orientada a objetos (POO, u OOP según sus siglas en inglés) es un paradigma de programación que viene a innovar la forma de obtener resultados. Los objetos manipulan los datos de entrada para la obtención de datos de salida específicos, donde cada objeto ofrece una funcionalidad especial.

Tal vez esta definición te deje con el culo torcido. Para aclarar las dudas y asentar las bases de la programación orientada a objetos has de saber que nuestros ordenadores contienen y procesan datos. Estos datos no dejan de ser información plana que carece de sentido por si mismos y que solo al ser analizados en un universo determinado y conocido obtienen el significado que nos es necesario para nuestros requisitos.

Me explico. Imagina que nuestro ordenador posee los siguientes datos:

Altura Anchura
50 20

Vale, vemos en la tabla que tenemos un dato que representa la altura, cuyo valor es 50, y tenemos otro dato que representa la anchura, que vale 20.

Pero ¿a qué representan estos valores? ¿Son las medidas de una persona? ¿Las medidas de una caja tal vez? ¿O las propiedades de un paquete de tabaco en un dibujo? Digo en un dibujo porque es un plano bidimensional tal y como lo son la altura y la anchura. Al no haber valor para la profundidad, plano Z, no podemos representar una caja o una persona de tres dimensiones, solo es un ejemplo educativo, no os pongáis tiquismiquis cabrones…

Pues bien, esa caja, esa persona o ese paquete de tabaco es a lo que me refiero con el universo concreto de los datos, es el contexto que le da sentido a los valores numéricos que hemos visto. Y como los datos y la informática es impersonal y carente de significado, la programación orientada a objetos es la herramienta que utilizamos para traducir esos valores a conceptos que conocemos de nuestra vida real.

La programación orientada a objetos como su nombre indica trabaja con objetos y nuestro paquete de tabaco del ejemplo es un objeto. Este objeto tiene propiedades como la altura y la anchura y encima puede realizar acciones por si mismo y puede ser sometido a acciones, como por ejemplo abrir el paquete, sacar un cigarrillo, comprobar que tenga tabaco o que el cartón del paquete se degrade.

Pues en la programación orientada a objetos, todo este conjunto de propiedades y acciones es lo que se conoce como objeto que es la representación abstracta de un objeto real de la vida real. ¿Se entiende?

Bueno, si todavía no te ha explotado la cabeza tomate un descanso, tomate un café o échate un piti porque vamos a entrar en faena a partir de aquí…

Representando los datos mediante las clases

Ya hemos visto cual es la definición de un objeto dentro de la programación orientada a objetos, pues bien una clase es la plantilla que vamos a utilizar para modelar este conjunto de datos o estos objetos vamos. Utilizamos las clases para representar entidades o conceptos y definen un conjunto de variables (propiedades) y de métodos (acciones).

Tal y como hemos visto, las clases y objetos suponen el pilar fundamental de la programación orientada a objetos.

Cuando estamos programando y utilizamos una clase, osea la plantilla, para crear un objeto digital, decimos que estamos instanciando una clase.

Para que nuestro ordenador nos entienda tenemos que escribir una clase tal que así:

Atención:

Tutorial basado en PHP. Si eres un Javero o defensor aferrimo de otros lenguajes y te entran pampurrias por favor vete 😛
Cada lenguaje utiliza diferentes sintaxis aunque compartan ciertos aspectos en común.

https://gist.github.com/gorkamu/48c0c5a623b69cb18cc1ac4f086aba30.js

Vale, tal y como puedes ver en el ejemplo, hemos definido la clase utilizando la palabra reservada class para a continuación nombrar a esta clase con el nombre PaqueteDeTabaco. El nombre de una clase puede ser cualquier nombre que te de la gana siempre y cuando no utilices una palabra reservada de esta lista.

Si te fijas bien, la clase tiene un conjunto de propiedades (altura y anchura) y de métodos (cualEsLaAltura, cualEsLaAnchura, abrirPaquete, comprobarSiHayTabaco, sacarCigarrillo)

Las propiedades tienen la palabra private delante de su definición y esto tiene que ver con las buenas prácticas en la programación orientada a objetos y con el encapsulamiento de datos. La palabra reservada private hace referencia al ámbito de las variables o como se diría en inglés al scope.

Existen varios tipos de ámbitos o de visibilidad de propiedades y métodos:

  • public: permite que el valor de la propiedad o el método sean accesibles desde cualquier lugar como por ejemplo otra clase u otras instancias de esa clase.
  • protected: hace que el valor de la propiedad o el método sea accesible desde la misma clase o desde cualquier otra que herede de ella.
  • private: hace que el valor de la propiedad o el método solamente sea accesible desde la misma clase que la define.

El valor de una propiedad no debería ser accesible desde fuera de una clase o desde otra clase sin utilizar un método que nos proporcione ese valor y aquí es donde entran los métodos getters y setters. Métodos get para recuperar un valor y métodos set para establecer un valor. Por ejemplo, si queremos acceder a la altura del paquete de tabaco tendríamos que hacerlo tal que así.

$paqueteDeTabaco->cualEsSuAltura();

Vuelve a fijarte en la definición de la clase que hay algo que todavía no he explicado… ¿Ya? ¿No te mosquea el uso de la palabra $this? ¿No sabes qué es?

Pues bien, la palabra $this es una pseudovariable, no forma parte de nuestra clase ni tenemos que definirla ni nada por el estilo, es una forma que nos da la sintaxis del lenguaje para poder acceder a elementos de una clase dentro de la misma clase ya sean propiedades o métodos y que solo funciona dentro de la clase.

Si intentas utilizar en cualquier lugar fuera de la clase te fallará.

Creando instancias de clases

Para crear la instancia de una clase y poder utilizarla en nuestro programa tendremos que utilizar la palabra reservada new.

$paqueteDeTabaco = new PaqueteDeTabaco();

Cualquier objeto se creará siempre y cuando tenga un constructor, pero ¿qué coño es un constructor?

Pues un constructor es el método que se encarga de construir el objeto, ¿obvio no? Un constructor se define tal que así:

function __construct() {
...
}

Al utilizar la palabra reservada new, internamente estamos llamando al constructor de la clase, aunque si te fijas en la clase del ejemplo, verás que no hay definido ningún constructor y esto es porque la clase utiliza el constructor por defecto, que al igual que con la pseudovariable $this no nos tenemos que preocupar de definir, ya nos lo provee el lenguaje.

Solo nos preocuparemos de definir siempre y cuando  queramos hacer algo específico en el proceso de construcción del objeto como por ejemplo inicializar variables o llamar a métodos de la clase.

Al igual que todo en la vida, todo lo que se crea se puede destruir y en la programación orientada a objetos no podría ser de otra forma. El lenguaje también nos provee de un método para destruir el objeto y esto es el destructor o la función destructora.

function __destruct() {
...
}

Generalmente utilizamos esta función para liberar memoria, aunque ese es un tema para otro post…

Otra cosa que podemos hacer con los objetos a parte de construirlos y destruirlos es clonarlos o lo que es lo mismo, hacer una copia de ellos mismos. Cuando se clona un objeto PHP hace una copia superficial de todas las propiedades del objeto. Si por cualquier caso una de estas propiedades es una referencia a otra variable el objeto clonado mantendrá esta misma referencia.

$paqueteDeMarlboro = new PaqueteDeTabaco();
$paqueteDeChester = clone $paqueteDeMarlboro;

Internamente al hacer una copia de un objeto estamos llamando al método mágico __clone().

Otro concepto importante en la programación orientada a objetos es la herencia.

Entendiendo la herencia

Entendiendo la herencia y digo entendiendo porque es un concepto bastante abstracto que tenemos que masticar muy detenidamente.

Volvamos al ejemplo del paquete de tabaco. Un paquete de tabaco es un concepto abstracto ya que nos imaginamos el concepto pero no somos capaces de identificar de que marca de tabaco se trata, si pertenece a tabaco negro o tabaco rubio o si se trata de cigarrillos hechos o de tabaco de liar.

Ahora si te imaginas un paquete de Ducados, otro de Marlboro y otro de Golden Virginia, estarás de acuerdo conmigo en que los tres son paquetes de tabaco y que entre ellos comparten ciertas características como la altura y la anchura del paquete pero se diferencian entre ellos del tipo de tabaco, de la presentación y de la marca.

Ademas estos tres paquetes pueden realizan acciones como abrir el paquete y/o saber cuantos cigarrillos quedan, sin embargo, por la fisionomía del packaging de los distintos paquetes, cada uno de ellos se pueden abrir de una forma diferente, por ejemplo…

Pues bien, si aplicamos esta lógica a la programación orientada a objetos, tendremos cuatro clases diferentes:

  • PaqueteDeTabaco.class.php
  • PaqueteDeDucados.class.php
  • PaqueteDeMarlboro.class.php
  • PaqueteDeGoldenVirginia.class.php

La clase PaqueteDeTabaco.class.php sería la clase padre y el resto de clases son las clases hijas que heredan de la clase padre. Mejor veamoslo con un dibujico…

Herencia en la programación orientada a objetos
Herencia en la programación orientada a objetos

Tal y como se ve en la imagen, cada una de las clases hijas comparten propiedades y métodos entre ellas gracias a la clase padre. Una instancia de la clase PaqueteDeDucados.class.php, otra de la clase PaqueteDeMarlboro.class.php y otra de PaqueteDeGoldenVirginia.class.php podrán utilizar el método abrirPaquete() y cualquiera de las tres podrán acceder al método cualEsLaAltura() para obtener el valor de la propiedad $altura de la clase padre y todo este gracias a la herencia.

Sin embargo, si preguntas al PaqueteDeDucados por su marca y tipo serán muy diferentes de las del PaqueteDeMarlboro.

$paqueteDeDucados->cualEsLaAltura();
$paqueteDeMarlboro->abrirPaquete();
$paqueteDeGoldenVirginia->comprobarSiHayTabaco();

Si nos ponemos puristas esto no sería del todo así ya que ambas clases hijas comparten marca y tipo de tabaco por lo que haciendo una buena refactorización deberíamos situar estas propiedades en la clase padre, pero para el ejemplo y para que sea mas visual nos vale.

Así pues, para que una clase herede de otra en PHP deberemos utilizar la palabra reservada extends en la definición de la clase.

Todos los métodos y propiedades de la clase padre pueden ser sobrescritos por las clases hijas. Esto quiere decir que, siguiendo el ejemplo, podemos re-definir el comportamiento de la función abrirPaquete() para una clase en concreto, por ejemplo para la clase del paquete de Golden Virginia ya que este tipo de tabaco no se vende en una cajetilla sino en un sobre y por lo que para abrir el paquete deberemos desenrollarlo en lugar de abrir la cajita, no se si me explico xD

Podremos sobrescribir un método padre siempre y cuando no haya sido definido como final.

Por otro lado, para acceder a una propiedad o llamar a un método padre desde una clase hija tenemos que utilizar la palabra reservada parent junto con el nombre del método.

https://gist.github.com/gorkamu/83780bea63001cf9c93ffc15a04ea721.js

Pues bien, como podemos ver en la clase de arriba, tenemos el método sacarCigarrillo() que pertenece a la clase padre pero que en este ejemplo de clase hija debemos re-definir ya que en el tabaco de liar los cigarros no vienen hechos sino que tenemos que coger un poco de tabaco, un papel y un filtro y liarlo.

A diferencia del resto de clases de paquetes de tabaco, el método sacarCigarrillo() nos devolvería un cigarro, sin tener que liarlo y por lo cual no haría falta sobrescribir este método.

 

Pues nada, obviamente quedan muchísimo mas conceptos por conocer y dominar en la programación orientada a objetos pero para ir entrando en faena creo que esta ha sido una buena primera aproximación.

Se que el tema ha sido largo y puede ser duro para una persona que nunca ha visto nada sobre lenguajes de programación así que si tienes algún tipo de duda o sugerencia puedes dejarme un comentario mas abajo o hacerlo a través de twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

¡Hala a mamarla!