1.2. Cada objeto tiene una interfaz

Aristóteles fue probablemente el primero en hacer un estudio minucioso del concepto de tipo; él habló de «la clase de peces y la clase de pájaros». La idea de que todos los objetos, aún siendo únicos, también son parte de una clase de objetos que tienen características y comportamientos comunes se utilizó directamente en el primer lenguaje orientado a objetos, Simula-67, con su palabra reservada class que introduce un nuevo tipo en un programa.

Simula, como su nombre indica, fue creado para desarrollar simulaciones como el clásico «problema del cajero» [12]. Tiene un grupo de cajeros, clientes, cuentas, transacciones, y unidades de moneda - un montón de «objetos». Los objetos idénticos, exceptuando su estado durante la ejecución del programa, se agrupan en «clases de objetos» y de ahí viene la palabra reservada class. Crear tipos de datos abstractos (clases) es un concepto fundamental en la programación orientada a objetos. Los tipos de datos abstractos trabajan casi exactamente como tipos predefinidos: puede crear variables de un tipo (llamadas objetos o instancias en el argot de la programación orientada a objetos) y manipular estas variables (llamado envío de mensajes o peticiones; envía un mensaje y el objeto decide qué hacer con él). Los miembros (elementos) de cada clase tienen algo en común: cada cuenta tiene un balance, cada cajero puede aceptar un depósito, etc. Al mismo tiempo, cada miembro tiene su propio estado, cada cuenta tiene un balance diferente, cada cajero tiene un nombre. De este modo, cada cajero, cliente, cuenta, transacción, etc., se puede representar con una única entidad en el programa de computador. Esta entidad es un objeto, y cada objeto pertenece a una clase particular que define sus características y comportamientos.

Por eso, lo que hace realmente un programa orientado a objetos es crear nuevos tipos de datos, prácticamente todos los lenguajes de programación orientados a objetos usan la palabra reservada class. Cuando vea la palabra «type», piense en «class» y viceversa [13].

Dado que una clase describe un conjunto de objetos que tienen idénticas características (elementos de datos) y comportamientos (funcionalidad), una clase es realmente un tipo de datos porque un número de punto flotante, por ejemplo, también tiene un conjunto de características y comportamientos. La diferencia está en que el programador define una clase para resolver un problema en lugar de estar obligado a usar un tipo de dato existente diseñado para representar una unidad de almacenamiento en una máquina. Amplía el lenguaje de programación añadiendo nuevos tipos de datos específicos según sus necesidades. El sistema de programación acoge las nuevas clases y les presta toda la atención y comprobación de tipo que da a los tipos predefinidos.

El enfoque orientado a objetos no está limitado a la construcción de simulaciones. Esté o no de acuerdo con que cualquier problema es una simulación del sistema que está diseñando, el uso de técnicas POO puede reducir fácilmente un amplio conjunto de problemas a una solución simple.

Una vez establecida una clase, puede hacer tantos objetos de esta clase como quiera, y manipularlos como si fueran elementos que existen en el problema que está intentando resolver. De hecho, uno de los desafíos de la programación orientada a objetos es crear una correspondencia unívoca entre los elementos en el espacio del problema y objetos en el espacio de la solución.

Pero, ¿cómo se consigue que un objeto haga algo útil por usted? Debe haber una forma de hacer una petición al objeto para que haga algo, como completar una transacción, dibujar algo en la pantalla o activar un interruptor. Y cada objeto puede satisfacer sólo ciertas peticiones. Las peticiones que puede hacer un objeto están definidas por su intefaz, y es el tipo lo que determina la interfaz. Un ejemplo simple puede ser una representación de una bombilla:

Clase Luz

Figura 1.1. Clase Luz


Luz luz1;
luz1.encender();

La interfaz establece qué peticiones se pueden hacer a un objeto particular. Sin embargo, se debe codificar en algún sitio para satisfacer esta petición. Ésta, junto con los datos ocultos, constituyen la implementación. Desde el punto de vista de la programación procedural, no es complicado. Un tipo tiene una función asociada para cada posible petición, y cuando se hace una petición particular a un objeto, se llama a esa función. Este proceso normalmente se resume diciendo que ha «enviado un mensaje» (ha hecho una petición) a un objeto, y el objeto sabe qué hacer con este mensaje (ejecuta código).

Aquí, el nombre del tipo/clase es Luz, el nombre de este objeto particular de Luz es luz1, y las peticiones que se le pueden hacer a un objeto Luz son encender, apagar, intensificar o atenuar. Puede crear un objeto Luz declarando un nombre (luz1) para ese objeto. Para enviar un mensaje al objeto, escriba el nombre del objeto y conéctelo al mensaje de petición con un punto. Desde el punto de vista del usuario de una clase predefinida, eso es prácticamente todo lo que necesita para programar con objetos.

El diagrama mostrado arriba sigue el formato del Lenguaje Unificado de Modelado (UML). Cada clase se representa con una caja, con el nombre del tipo en la parte de arriba, los atributos que necesite describir en la parte central de la caja, y los métodos (las funciones que pertenecen a este objeto, que reciben cualquier mensaje que se envíe al objeto) en la parte inferior de la caja. A menudo, en los diagramas de diseño UML sólo se muestra el nombre de la clase y el nombre de los métodos públicos, y por eso la parte central no se muestra. Si sólo está interesado en el nombre de la clase, tampoco es necesario mostrar la parte inferior.



[12] Puede encontrar una implementación interesante de este problema en el Volumen 2 de este libro, disponible en www.BruceEckel.com

[13] Hay quien hace una distinción, afirmando que type determina la interfaz mientras class es una implementación particular de esta interfaz.