Abstracción en Programación Orientada a Objetos

  • Por
Concepto de abstracción en el paradigma de la Programación Orientada a Objetos y situaciones en las que se puede y se debe aplicar.

Abstracción es un término del mundo real que podemos aplicar tal cual lo entendemos en el mundo de la Programación Orientada a Objetos. Algo abstracto es algo que está en el universo de las ideas, los pensamientos, pero que no se puede concretar en algo material, que se pueda tocar.

Pues bien, una clase abstracta es aquella sobre la que no podemos crear especímenes concretos, en la jerga de POO es aquella sobre la que no podemos instanciar objetos. Ahora bien, ¿cuál es el motivo de la existencia de clases abstractas? o dicho de otra manera, ¿por qué voy a necesitar alguna vez declarar una clase como abstracta?, ¿en qué casos debemos aplicarlas? Esto es todo lo que pretendemos explicar en este artículo.

Abstracción en el mundo real

La programación orientada a objetos sabemos que, de alguna manera, trata de "modelizar" los elementos del mundo real. En el mundo en el que vivimos existe un universo de objetos que colaboran entre sí para realizar tareas de los sistemas. Llevado al entorno de la programación, también debemos programar una serie de clases a partir de las cuales se puedan instanciar objetos que colaboran entre sí para la resolución de problemas. Si asumimos esto, a la vista de las situaciones que ocurren en el mundo real, podremos entender la abstracción.

Cuando estudiamos en el concepto de Herencia en Programación Orientada a Objetos vimos que con ella se podían definir jerarquías de clasificación: los animales y dependiendo de éstos tenemos mamíferos, vertebrados, invertebrados. Dentro de los mamíferos tenemos vacas, perros…

Animal puede ser desde una hormiga a un delfín o un humano. En nuestro cerebro el concepto de animal es algo genérico que abarca a todos los animales: "seres vivos de un "reino" de la existencia". Si defines animal tienes que usar palabras muy genéricas, que abarquen a todos los animales posibles que puedan existir en el mundo. Por ello no puedes decir que animales son aquellos que nacen de huevos, o después de un periodo de gestación en la placenta.

Adonde quiero llegar es que el animal te implica una abstracción de ciertos aspectos. Si lo definimos con palabras no podemos llegar a mucho detalle, porque hay muchos animales distintos con características muy diferentes. Hay características que se quedan en el aire y no se pueden definir por completo cuando pensamos en el concepto de animal "genérico".

Para acabar ¿en el mundo real hay un "animal" como tal? No, ni tan siquiera hay un "mamífero". Lo que tenemos son especímenes de "perro" o "vaca", "hormiga", "cocodrilo", "gorrión" pero no "animal" en plan general. Es cierto que un perro es un animal, pero el concepto final, el ejemplar, es de perro y no animal.

Por tanto "animal", en términos del lenguaje común, podemos decir que es un concepto genérico, pero no una concreción. En términos de POO decimos que es un concepto abstracto, que implementaremos por medio de una clase abstracta. No instanciaremos animales como tal en el mundo, sino que instanciaremos especímenes de un tipo de animal concreto.

En los animales existen propiedades y métodos que pueden ser comunes a todos los animales en general. Los animales podrán tener un nombre o una edad, determinadas dimensiones o podrán desempeñar acciones como morir. Lo que nos debe quedar claro es que no deberíamos poder instanciar un animal como tal. ¿Cómo nace un animal en concreto?, ¿cómo se alimenta? Para responder a esas preguntas necesitamos tener especímenes más concretos. Sí que sé cómo nace o cómo se alimenta una hormiga, o un gorrión, pero no lo puedo saber de un animal genérico, porque puede hacerlo de muchas maneras distintas.

Seguiremos trabajando para explicar estos conceptos, pero de momento entendemos que "animal" es una clase abstracta, pero "hormiga", "perro" o "gorrión" no serían clases abstractas, que sí podríamos instanciar.

Herencia y abstracción

Si entendemos el concepto de herencia podremos entender mejor la abstracción y cómo se implementa.

Recuerda nuestro ejemplo: Tengo animales. Hemos acordado que no puedo tener un animal concreto instanciado en un sistema. Si acaso tendré instancias de perros, saltamontes o lagartijas. Pues bien, en los esquemas de herencia este caso nos puede surgir muy habitualmente.

En la clase "animal" puedo tener determinadas propiedades y acciones implementadas. Por ejemplo, todos los animales pueden tener un nombre, o una edad (ya sean segundos, días o años de edad). También es posible que pueda definir diversas acciones de una vez para todos los animales de una jerarquía de herencia, por ejemplo, la acción de morir, pues todos morimos igual (simplemente dejamos de existir aunque aquí dependiendo de las creencias de cada uno esto pueda ser discutible).

Aunque mi sistema no pueda crear animales como tal, tener definidas esas cuestiones comunes a todos los animales me resulta útil para no tener que programarlas de nuevo en todos los tipos de animales que puedan existir. Simplemente las heredaré en las clases hijas, de modo que estarán presentes sin tener que volver a programar todas esas cosas comunes.

Sin embargo hay cosas de los animales que no podré implementar todavía. Atributos como el número de patas, el alcance de la visión, se implementarán a futuro en los tipos de animales que las necesiten, pero fijémonos en las acciones o métodos. Por ejemplo nacer, alimentarse, etc. No sé cómo va a nacer un animal, pero sé que todos los animales del mundo nacen de algún modo (unos nacen de huevos, otros estaban en la barriga de las hembras y nacen a consecuencia de un parto, etc.)

En estos casos nos puede ser útil definir como métodos abstractos en la clase "animal" esos métodos que van a estar presentes en todos los animales, aunque no seamos capaces de implementarlos todavía.

public abstract function nacer();

Esto quiere decir que todos los animales del mundo heredarán un método abstracto llamado nacer. En las clases concretas que hereden de animal y donde ya sepamos cómo nace tal animal, por ejemplo, la gallina, podemos implementar ese método, para que deje de ser abstracto.

public function nacer(){
	//se rompe el huevo y nace el pollito que más adelante será una hermosa gallina
}

Hasta ahora sabemos que hay clases que tienen métodos abstractos, que no somos capaces de implementar todavía y clases en las que se heredan métodos abstractos y en las que seremos capaces de implementarlos.

La utilidad de esto la entenderemos mejor en unos instantes, al tratar el polimorfismo, pero de momento debemos ser capaces de asimilar estas definiciones más formales:

"Una clase abstracta es aquella en la que hay definidos métodos abstractos, sobre la que no podremos instanciar objetos" Además, en un esquema de herencia, "Si heredamos de una clase abstracta métodos abstractos, tampoco se podrán instanciar objetos de las clases hijas y tendrán que definirse como abstractas, a no ser que implementemos todos y cada uno de los métodos que se habían declarado como abstractos en la clase padre".

Polimorfismo y abstracción

Creo que si no se examina de cerca la abstracción bajo el prisma del polimorfismo no se puede entender bien la verdadera utilidad de hacer clases abstractas. Pero antes de seguir, recuerda qué es el Polimorfismo en Programación Orientada a Objetos.

Cuando hablamos de polimorfismo explicamos que es una relajación del sistema de tipos por la cual éramos capaces de aceptar objetos de un tipo y de todas las clases hijas. Por ejemplo, tengo la clase "PoligonoRegular". Sé que los polígonos regulares voy a querer conocer su área, pero para saber su área necesito conocer el número de lados que tiene. Entonces la clase "PoligonoRegular" tendrá un método abstracto "dameArea()". Luego, al definir la clase "cuadrado", o el "pentágono", etc. podremos implementar tal método, con lo que dejará de ser abstracto. Tenemos "Alumnos de una Universidad", los alumnos los vas a querer matricular en las universidades, pero dependiendo del tipo de alumno la matrícula se hace diferente, pues no es lo mismo matricular un alumno becario, o de familia numerosa, que uno normal. Entonces, en la clase "alumno" tendré un método abstracto que sea "matriculate()" que podré definir del todo cuando implemente las clases hijas.

Ahora piensa en esto. Gracias a que fueron definidos los métodos abstractos "dameArea()" y "matriculate()" en las clases padres, tengo clara una cosa: cuando trabajo con elementos de la clase "poligonoRegular", sé que a todos los polígonos regulares que pueda recibir les puedo pedir que me devuelvan su área. También sé que a todos los alumnos les puedo pedir que se matriculen en una universidad.

Ahí está la potencia del polimorfismo, recibir un objeto que pertenece a una jerarquía de clasificación y saber que puedo pedirle determinadas cosas. Quizás en la clase padre no pudieron implementarse esos comportamientos, porque no sabíamos el código necesario para ello, pero al menos se declararon que iban a poder realizarse en el futuro en clases hijas. Eso me permite, en un esquema de polimorfismo, que pueda estar seguro que todos los objetos que reciba puedan responder a acciones determinadas, pues en las clases hijas habrán sido definidas necesariamente (si no se definen deberían declararse las clases como abstractas y en ese caso es imposible que me manden objetos de esa clase).

Es cierto que el concepto se puede quedar un poco en "la abstracción" pero cuando practiques un poco te darás cuenta de la esencia de las clases abstractas y entenderás lo útil y necesario que es declarar métodos abstractos para poder implementar el polimorfismo. De momento es todo en cuanto a este concepto, esperamos que este texto te haya servido de algo. Por supuesto, se agradecen los comentarios.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Adrian

21/5/2014
Muy bueno...
El articulo está excelente y muy fácil de entender... Saludos!
@jeromeelf

nacho

21/5/2014
muy bueno
genial, justo para la U. :D

Jean

22/5/2014
Bien
Excelente!

Luis

22/5/2014
Felicidades
Esta muy bien explicado, lo difícil es llevarlo a la practica con el lenguaje de tu preferencia

Gracias por el aporte

lpuschel

26/5/2014
buenisimo
excelente trabajo, cuando uno aprende a programar en la universidad se olvida de algunos conceptos claves, se agradece el aporte.

Edgardo

27/5/2014
Clarisimo
Estos temas se han explicado hasta la saciedad, en el mundo entero, pero siempre queda algo que no se entiende.
En este caso, al reves , se entiende muy bien lo explicado.
Entonces queda claro, No todos sabemos enseñar.Muchas veces salimos mas confundidos.
Saludos.

Jorge A. Correa

27/5/2014
Excelente artículo
Al terminar de leerlo recordé esos dos importantes conceptos que se utilizan en la POO. Excelente artículo!.

cristian alexander

31/7/2014
agradecimiento
gracias a personas como usted, que permiten que los conocimiento se expanda y con calidad.
los artículos son fantásticos. muchas gracias.

JavierB

30/10/2014
Comentario
Muy buen articulo, enhorabuena!

Jorge Alexander

26/12/2014
Excelente
Lo entiendo es lo importante compartir pero que los demás entiendan

jeluchez

28/1/2015
Agradecimiento
Muchas gracias por este articulo que es muy bien explicado

Anahi

29/1/2015
Simplemente Perfecto
Cuando me explicaron estos conceptos en la uni me quedo un poco de duda. Pero gracias a esta explicación terminé por entenderlo; esta muy bien explicado y con ejemplos faciles de entender. Felicitaciones!!!!!!!!. Saludos!!!

Tomas

20/2/2015
Cielo abierto
He leido y mucho sobre POO, pero nunca tan sencillo de entender y fluido como en estos tres articulos.

Un saludo y muchas gracias.

José

08/4/2015
MUY BUEN ARTICULO
me gusta mucho tu articulo ya que no solo te ayuda a entender el concepto que preguntas sino que te enseña tambien lo que esta implicado en cada concepto para entenderlo de una mejor manera. crack

Gonzalo Marambio

17/7/2015
Espectacular
Me quedo super claro el concepto de abstracción, te agradezco el tiempo y dedicación

Ivan Grosse

06/3/2016
Buenísimo
La verdad estan muy buenos todos tus artículos sobre los pilares de la POO, muy claros y didácticos

Irene Rodriguez

26/5/2016
Muchas gracias
Estoy estudiando Desarrollo de Aplicaciones Web y me vienen genial tus artículos. Ahora mismo para la asignatura Entornos de Desarrollo, la parte de Diagrama de Clases, que tiene muchos conceptos complicados de asimilar y tus textos son muy útiles para conseguirlo. Mil gracias por tu esfuerzo, tu tiempo y tu trabajo.
Un abrazo,

Irene.

Eduardo

21/6/2016
Excelente aporte!!!
Excelente aporte!!!

martha liliana avellaneda

09/8/2016
Gratitud
Excelente articulo, que buena manera de relacionar los conceptos con ejemplos claros y reales,muchas gracias pude comprender mejor la variedad de conceptos.

Lizeth

20/10/2016
Exelente!
Estos artículos ayudan mucho por su buena redacción hace que se pueda entender muy facilmente.

David Martinez

27/1/2017
¡Muy bien explicado!
Explicado de forma sencilla y llegando al detalle.
Excelente artículo y así podemos mostrar que la orientación a objetos no es tan complicada como la pintan.
Gracias

Raúl

03/2/2017
Muy bie.
Gracias por vuestra publicación, aún sigo sin entender mucho de esto pero en eso estoy, aprendiendo. Agradecería que me pudieran dar más ejemplos prácticos de la abstracciónn