Programación Orientada a Objetos – Clases abstractas e interfaces.

¡Bienvenidos un día más a un nuevo rootie queridos amigos! Empieza la semana y como empieza a ser nuestra costumbre volvemos a la carga. La semana pasada hablamos sobre diferentes temas y publicamos nuestro vigésimo rootie (que para los de la LOE, LOMCE o la Universidad de la Calle es el número 20) y además durante el fin de semana, Susan se ha currado esta pedazo de página para llevar la cuenta sobre los temas que hablamos en ohmyroot!. Pero bueno, que me voy por los cerros de Úbeda, esta semana vamos a hablar de clases abstractas e interfaces.

Clases abstractas.

En la programación orientada a objetos, podemos encontrar diferentes tipos de clases y entre ellas una que cobra gran relevancia es la clase abstracta. El mismo nombre del tipo de clase nos da una pista sobre su comportamiento, ya que algo abstracto en el mundo real es algo que pertenece al mundo de las ideas, que no puede ser definido de forma material. Una clase abstracta en el paradigma de la POO no es más que una clase que no puede ser instanciada.

La abstracción, pues, es el acto de aislar un elemento del contexto o del resto de elementos del sistema, de esta forma nos concentramos en entender que va a hacer sobre el como lo va a hacer. Para entender esto veámoslo con un ejemplo.

Poniendo en practica la abstracción.

Imaginemos que tenemos que crear un sistema para clasificar a nuestros seguidores y detractores (o haters; hola DarkSoldier!). Puede que el primer impulso fuese crear dos clases: Seguidores y Detractores, pero si aplicamos el principio de abstracción podemos ver que ambos grupos, probablemente, estarán compuestos de personas, con lo que muchas propiedades van a ser comunes, por lo que lo mejor sería crear una clase Persona.

Antes de seguir veamos un poco más en profundidad este ejemplo.

En la clase hemos definido tres propiedades que van a ser comunes, y hemos definido una función publica y una firma de una función abstracta. Aquí hay varias cosas interesantes, si utilizáramos esta clase como la clase padre, tendríamos que tener en cuenta que para poder instanciar una clase hija de una forma satisfactoria, esta última deberá implementar la función getFullName(), haciendo uso de la lógica que mas nos gustase.

Ademas a la hora de realizar esta implementación en la clase hija, se deberán tener en cuenta los parámetros definidos en la firma (aunque aquí no haya ninguno) que deberán coincidir en número y tipo, sino obtendremos un error. Dependiendo del lenguaje podremos añadir parámetros opcionales, como sucede con PHP. Otra cuestión importante es la visibilidad, ya que esta nunca puede ser mas restrictiva que la declarada en la clase abstracta. Si una propiedad/método es protected en tu clase hija, solo podrá ser protected o public nunca private.

Por lo tanto una clase hija que fuese totalmente valida sería algo así:

Como se puede ver, he creado esta nueva clase agregando nuevas propiedades, implementando la función abstracta, agregándole un parámetro extra (que será el separador) y agregando una nueva función publica que usara getFullName() para retornar un texto.

Para no dejar el ejemplo inacabado, aquí os pego también la clase Admirador:

autografo clases abstractas
Todo este ejemplo esta escrito por Gilderoy Lockhart

Conclusiones de la abstracción.

Como podemos ver la abstracción es una potente herramienta a la hora de trabajar, ya que nos va a permitir modelar nuestro sistema basándonos en conceptos más generales y en como deben funcionar la relación de objetos del sistema, que en la concreción de los mismos. También cabe destacar que la abstracción va íntimamente ligada a la herencia, que ya vimos en el anterior rootie, pero además toma gran relevancia para conseguir un buen nivel de polimorfismo.

Interfaces.

Una vez que ya hemos visto la clase abstracta, veamos pues que es una interfaz, algo que muchos estudiantes de programación e incluso programadores encuentran difícil de entender.

Una interfaz en el ámbito de la POO es un objeto que no contiene ni datos ni código, pero define comportamientos en forma de firmas de métodos. La interfaz no proporciona una implementación de ninguno de sus métodos, esto recae siempre en la clase que implemente dicha interfaz. Como nota, una clase puede implementar varias interfaces al mismo tiempo frente a que esa misma clase solo puede heredar de una única clase padre.

«¡Wow! Esto suena muy parecido a una clase abstracta», me vais a decir y os contestaría, pues si, si que lo es, pero hay una (no tan sutil) diferencia.

La interfaz va a definir exclusivamente métodos vacíos y públicos, que nos obligarán a implementarlos en la clase, pero ninguna indicación de como debe ser dicha implementacion, frente a la clase abstracta, que puede definir métodos completos. Además una interfaz no puede contener atributos de clase (excepto si definimos constantes) mientras que una clase abstracta puede sin ningún problema y con diferentes niveles de accesibilidad.

Entonces, ¿cual es su utilidad?

Las interfaces nos ofrecen ciertas ventajas frente a las clases abstractas:

  • Establecer relaciones entre clases que no están relacionadas.
  • Se puede simular la herencia múltiple.

Sobre las ventajas, sinceramente no soy un gran fan de la herencia múltiple, pero el poder relacionar clases que no lo están, abre siempre muchísimas e interesantes posibilidades.

Usando interfaces.

Y no, no se usan para esto.

Para declarar una interfaz, normalmente se utiliza la palabra reservada interface (¡¿original eh!?) en donde normalmente utilizamos la palabra class y para utilizarla en nuestras clases, usaremos la palabra implements después del nombre de la clase y el nombre de la interfaz, veamos un ejemplo:

Y aquí podemos ver la implementación de la misma en la clase Admirador:

Como se puede ver, ahora la clase Admirador implementa una función extra definida en la interfaz. Dicha función no es estrictamente algo que definiríamos siguiendo el ejemplo de comparación de objetos frente al mundo real, pero ahí está la gracia de la interfaz.

Y con esto terminamos por hoy, espero que este rootie sea de utilidad, ya que trata dos aspectos del POO que siempre resultando escabrosos y difíciles de comprender cuando se esta aprendiendo.

Para cualquier duda, pregunta, comentario, soborno o amenaza, podéis usar los comentarios o en nuestras redes sociales Facebook y Twitter.

 

One Comment

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *