Programación Orientada a Objetos ¿Usamos sus innumerables ventajas?

A esta altura ya casi todos los programadores conocen lo que es la Programación Orientada a Objetos (OOP, por sus siglas en inglés). Los que no, es hora de que empiecen a informarse; de lo contrario no sólo se pierden de sus innumerables ventajas, sino que pronto podrían quedar fuera del mercado, y ojo con esto que definitivamente es una gran responsabilidad que debe tener todo desarrollador. Pues quienes aún no usan este paradigma de programación los invito a revisar la gran cantidad de información que existe en la red.

Lo que puedo aportar como resumen en este espacio es decir (de acuerdo a mi propia experiencia) que La Programación Orientada a Objetos es un paradigma de programación que define los programas en términos de «clases de objetos», objetos que son entidades que combinan estado (es decir, datos), comportamiento (esto es, procedimientos o métodos) e identidad (propiedad del objeto que lo diferencia del resto). La programación orientada a objetos expresa un programa como un conjunto de estos objetos, que colaboran entre ellos para realizar tareas. Esto permite hacer los programas y módulos más fáciles de escribir, mantener y reutilizar.

Características de la POO (Extraído de Wikipedia)

Hay un cierto desacuerdo sobre exactamente qué características de un método de programación o lenguaje le definen como «orientado a objetos», pero hay un consenso general en que las características siguientes son las más importantes (para más información, seguir los enlaces respectivos):

  • Abstracción: cada objeto en el sistema sirve como modelo de un «agente» abstracto que puede realizar trabajo, informar y cambiar su estado, y «comunicarse» con otros objetos en el sistema sin revelar cómo se implementan estas características. Los procesos, las funciones o los métodos pueden también ser abstraídos y cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción.
  • Encapsulamiento: también llamado «ocultación de la información». Cada objeto está aislado del exterior, es un módulo natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas, solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no pueden cambiar el estado interno de un objeto de maneras inesperadas, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce a un agregado o rompecabezas de objetos.
  • Polimorfismo: comportamientos diferentes, asociados a objetos distintos, pueden compartir el mismo nombre, al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. O dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en «tiempo de ejecución», esta última característica se llama asignación tardía o asignación dinámica. Algunos lenguajes proporcionan medios más estáticos (en «tiempo de compilación») de polimorfismo, tales como las plantillas y la sobrecarga de operadores de C++.
  • Herencia: las clases no están aisladas, sino que se relacionan entre sí, formando una jerarquía de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento permitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que reimplementar su comportamiento. Esto suele hacerse habitualmente agrupando los objetos en clases y estas en árboles o enrejados que reflejan un comportamiento común. Cuando un objeto pertenece a más de una clase se llama herencia múltiple; esta característica no está soportada por algunos lenguajes (como Java).