Todo lenguaje de programación ofrece un proceso de abstracción sobre un concepto extraído del mundo real, en otras palabras, un lenguaje permite un mapeo entre un problema espacial(real) hacia uno maquinal que será aquel ejecutado por una computadora. Es en esta capacidad de abstracción es que reside la facilidad/complejidad de generar programas funcionales capaces de resolver el problema espacial.
El lenguaje ensamblador es una abstracción de la maquina ejecutora ("procesador"); lenguajes como Fortran, Basic y C son abstracciones de este mismo lenguaje ensamblador, sin embargo, aunque estos últimos ofrecen un avance sobre el lenguaje ensamblador, estos aún requieren de procesos de abstracción considerables.
Lo anterior produce programas que son difíciles de escribir y actualizar por la simple razón que el problema espacial dista en grandes proporciones del mapeo maquinal; frente a estas deficiencias han surgido lenguajes más apegados al problema real tales como: PROLOG donde todo problema es mapeado a una cadena de decisiones o LISP donde todo problema es convertido a listas.
Aquí es donde los lenguajes orientados a objetos salen a relucir, esto se debe a que permiten llevar acabo un mapeo más directo con el problema espacial(real). Allan Kay, describió las 5 principales características de Smalltalk, uno de los primeros lenguajes orientados a objetos y uno de los lenguajes en los cuales esta basado Java:
Todo es un objeto: Considere un objeto una variable especial, no solamente guarda datos, sino también se pueden hacer solicitudes a este Objeto en sí. En teoría, cualquier elemento en el problema espacial(real) (edificios, servicios, automóviles, u otra entidad) puede ser representado como un objeto en un programa.
Un programa es un conjunto de Objetos, enviándose mensajes entre sí : Para realizar una solicitud a un Objeto es necesario enviarle un mensaje. Concretamente se puede pensar que un mensaje es una solicitud para llamar una función que pertenece a cierto objeto.
Cada Objeto tiene su memoria, conformada por otros Objetos : En otras palabras, es posible generar un tipo de Objeto nuevo agrupando Objetos existentes. De esta manera se pueden armar estructuras complejas en un programa, escondidas detrás de la simplicidad de Objetos.
Todo Objeto tiene su Tipo: En este sentido Tipo se refiere a Clase, donde cada Objeto es una instancia de una Clase en cuestión.La característica más importante de una Clase es el tipo de mensajes que pueden ser enviados a ella.
Todo Objeto de un mismo tipo puede recibir los mismos mensajes : Esto implica que si un Objeto es del tipo Circulo, un Objeto del tipo Figura será capaz de recibir mensajes de Circulo, puesto que un Circulo es una Figura. Este concepto forma parte medular de todo lenguaje orientado a Objetos y será explorado en una sección especifica de este curso.
En la gráfica anterior se puede observar una Clase conformada por una Lampara (problema espacial real) a la cual pueden ser enviados distintos mensajes tales como: prender, apagar, girar
y cambiar
; para crear un Objeto de esta Clase y ser utilizado dentro de un programa es necesario generar una instancia del mismo, esto se demuestra a continuación:
Lampara candil = new Lampara(); candil.prender(); |
El primer renglón genera una instancia de la Clase Lampara la cual es asignada a la referencia candil; en la segunda linea, a través de esta referencia se manda llamar el método prender()
definido en la misma Clase; a través de referencias es posible generar distintos Objetos del mismo tipo cada uno con su propio comportamiento:
Lampara candil = new Lampara(); Lampara manual = new Lampara(); Lampara jardin = new Lampara(); candil.prender(); candil.girar(); manual.apagar(); jardin.prender(); jardin.elevar(); candil.apagar(); |
Lo anterior demuestra una de las principales características de los lenguajes orientados a Objetos, sin embargo, a continuación se describen las características especificas del Lenguaje Java y porque es considerado uno de los más avanzados en su ramo.
Entre los lenguajes orientados a Objetos hoy en día Java figura entre los más utilizados comparado con sus homólogos, pre-aparición de Java el lenguaje C++ se encontraba en la cúspide para desarrollos de Software con orientación a Objetos, sin embargo, Java ha venido suplantando su uso debido a dos características muy especificas que C++ no ofrece.
Esta característica forma parte del lema Java: "Write once, run everywhere" (Escribalo una vez, ejecutelo en todos lados), a continuación se ilustra este concepto.
El proceso de creación es muy similar a la de otros lenguajes: una vez creado el Código Fuente es necesario compilarlo para generar un binario, este binario denominado Byte-Code en Java lleva por extensión .class
, sin embargo, a diferencia de otros lenguajes este binario (Byte-Code) puede ser ejecutado en diversas plataformas obteniéndose el mismo resultado final.Esta interoperabilidad de ejecución se debe a que el Byte-Code es ejecutado en una maquina virtual llamada "Java Virtual Machine", es a través de este componente que se logra una ejecución idéntica en distintos ambientes.
Hoy en día, existen diversos JVM("Java Virtual Machines") para distintas plataformas y ambientes que oscilan desde los Sistemas Operativos Linux,Solaris,Windows,HP-UX hasta productos como Bases de Datos Oracle y Servidores de Aplicaciones BEA; esto permite que código escrito en Java pueda ser ejecutado en cualquier ambiente produciéndose los mismos resultados.
En la sección anterior se pudo observar como son generadas distintas instancias de Objetos a través de una referencia, sin embargo, el uso de esta metodología trae consigo otro pregunta : Que se hace con estas instancias una vez que ya no son utilizadas ? La importancia de este concepto se debe al uso de memoria en una computadora, es lógico que estas instancias de Objetos requieren memoria ("RAM") para mantener su información, ahora bien, también tiene sentido asumir que la memoria ("RAM") es limitada en todo sistema, esto trae consigo el problema denominado "fuga de memoria" ("memory leak").
Si alguna vez ha programado en el lenguaje C++ debe estar familiarizado con este concepto, el cual significa que los recursos de memoria ("RAM") han sido agotados en el sistema. Suponga que ha diseñado un programa que invoca la creación de miles de instancias , eventualmente su memoria ("RAM") puede fugarse si no ha tomado las precauciones necesarias para deshacerse/destruir estas instancias de Objetos.
En el mundo Java, esta administración explicita de instancias de Objetos no es necesaria debido al proceso de "Garbage Collection"; este mecanismo a través del JVM ("Java Virtual Machine") inspecciona constantemente la memoria empleada por Java, lo cual le permite ir eliminando las instancias de Objetos que han dejado de ser utilizadas en un programa, en el proceso despreocupándose de la destrucción de Objetos.
Aunque el concepto de recolección de basura ("Garbage Collection") posee una infinidad de detalles en su fondo, es conveniente saber que este proceso es llevado automáticamente por Java, y que es una facilidad no ofrecida en otros lenguajes como C++
JDK ("Java Development Kit") y J2SE ("Java 2 Standard Edition") son nombres para el mismo componente utilizado en ambientes Java, el cual agrupa las diversas funcionalidades necesarias para desarrollar programas Java.
Hoy en día, existen JDK's/J2SE para diversos ambientes y plataformas, los cuales ofrecen lo siguiente:
Un compilador Java, capaz de generar Byte-Code.
Un JVM ("Java Virtual Machine"), capaz de ejecutar Byte-Code.
Un conjunto de Clases base utilizadas para generar programas Java.
Otras utilerías para administrar código escrito en Java.
Para este curso se hace uso del JDK/J2SE de Sun Microsystems , aunque claro esta, cualquier programa generado en este JDK puede ser ejecutado otros ambientes, al igual que programas compilados en otros JDK's/J2SE pueden ser ejecutados en este ambiente. El conjunto de Clases base proporcionadas por el JDK/J2SE incluyen clases de uso común tales como : Manipulación de String's, Fechas y Números así como todas las funcionalidades base esperadas de un lenguaje computacional como: Ordenamiento y manipulación de Arreglos, Operaciones matemáticas complejas (Trigonométricas y Exponenciales) y escritura/lectura de "Streams".
Además de estas Clases base, el JDK/J2SE posee otra serie de Clases especializadas que también ofrecen la base para la creación de otros componentes Java que incluyen : Applets, Objetos CORBA , Fragmentos Auditivos, Soporte de Criptografía (Seguridad) y Manipulación de XML entre otras funcionalidades.
Aunado a las Clases base, el JDK/J2SE incluye una serie de ejecutables utilizados para diversas tareas como : Creación de ejecutables (Byte-Code), generación de documentación, creación de "Stubs" y "Skeletons" a través de IDL e inclusive una implementación de un ORB ("Object Request Broker") para interactuar con ambientes CORBA, entre otros ejecutables.
La estructura de directorios del JDK/J2SE es la siguiente:
JDK 1.4.2 ___________|_________________ | | | bin lib jre | | ________|__________ java* tools.jar | | javac* dt.jar bin lib javap* | ________ ___|___ _________ ________ _______ javah* java* | | | | | | javadoc* rt.jar ext security i386 applet fonts charsets.jar | / \ | / \ localedata.jar server client
Como se puede observar, la estructura se encuentra dividida en tres grandes partes :
bin
: Incluye los ejecutables para la generación de programas Java.
lib
: Contiene las librerías (Clases) base empleadas en la generación de la gran mayoría de programas Java.
jre
: Incluye el ambiente necesario para ejecutar programas Java, el cual a su vez se encuentra sub-dividido en distintos directorios.
Dependiendo de la manera en que haya instalado la documentación del JDK, se recomienda observarla en estos momentos para que se familiarice con sus Clases Base. |