Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 34

Índice

1. PROGRAMACIÓN ORIENTADA A OBJETOS.


1.1. Introducción a la Programación
Orientada a Objetos.
1.2. Clases.
1.3. Creación de una clase.
1.4. Objetos
1.5. Ejemplo Práctico con Objetos.
1.6. Ejemplo Práctico con Objetos II.
1.7. Interacción entre los elementos.
1.8. Ejemplo Interacción entre elementos.
1.9. Interfaces II.

1.10. Peculiaridades de Java.

Campus Impúlsate | [email protected]


Contenido

1.1. Introducción a la Programación


Orientada a Objetos.

Hoy en día el paradigma de orientación a objetos es el más utilizado para programar y


prácticamente lo podemos encontrar en la mayoría de los lenguajes de programación
más utilizados: Java, PHP, C++, etc.

La programación orientada a objetos (POO, u OOP según sus siglas en inglés) no es más
que un paradigma de programación que viene a innovar la forma de obtener resultados.
Los objetos manipulan los datos de entrada para la obtención de datos de salida
específicos, donde cada objeto ofrece una funcionalidad especial.

Muchos de los objetos prediseñados de los lenguajes de programación actuales


permiten la agrupación en bibliotecas, sin embargo, muchos de estos lenguajes
permiten al usuario la creación de sus propias bibliotecas.

La POO se basa en varias técnicas, incluyendo herencia, cohesión, abstracción,


polimorfismo, acoplamiento y encapsulamiento.

En un entorno más clásico de programación el problema o sistema que se está


analizando se divide en funciones, cada función solo operaba con sus parámetros de
entrada y no modificaba información externa a ella.

Para llevar a cabo el análisis con la programación orientada a objetos hay que tener en
cuenta que los programas se codifican pensando en objetos que interactúan.

Los objetos tendrán unas determinadas propiedades y serán capaces de hacer ciertas
cosas mediante los métodos (funciones) que se les hayan definido en plantillas
denominadas clases.

Si se hace un buen diseño de los objetos y su interacción, se podrán usar en nuevos


programas y proyectos fácilmente, favoreciendo la reusabilidad.

A lo largo de la historia de la informática, han ido apareciendo diferentes paradigmas de


programación. En primer lugar, apareció la programación secuencial, que consistía en
secuencias de sentencias que se ejecutaban una tras otra. El lenguaje ensamblador o el
lenguaje COBOL son lenguajes secuenciales. Entonces no existía el concepto de
función, que apareció más adelante en los lenguajes procedimentales, como el BASIC o
el C. La evolución no terminó aquí, y continuó hasta el paradigma más extendido en la
actualidad: la programación orientada a objetos. Smalltalk, C++ o Java pertenecen a
esta nueva generación.

Campus Impúlsate | [email protected]


Cada nuevo paradigma ha extendido el anterior, de manera que podemos encontrar las
características de un lenguaje secuencial en uno procedimental, y las de uno
procedimental en uno orientado a objetos.

Un poco de historia
JAVA fue creado como una herramienta de programación para ser usada en un proyecto
de set-top-box en una pequeña operación denominada the Green Project en Sun
Microsystems en el año 1991. El Green Team, el cual está compuesto por 13 personas
contando con James Gosling a la cabeza, trabajó durante 18 meses en Sand Hill Road
en Menlo Park en su desarrollo.

El lenguaje fue denominado de manera iniciar como Oak (nombre que fue dado gracias
a un roble que había fuera de la oficina), después cambió su denominación a "Green"
tras descubrir que Oak era una marca comercial de adaptadores de tarjetas gráficas, así
que posteriormente cambió su nombre al de JAVA.

Es frecuentada por algunos de los miembros del equipo. Lo que no está claro es de si
se trata de un acrónimo o no, aunque hay ciertas fuentes que hacen indicar que son las
iniciales de sus diseñadores: J ames Gosling, A rthur V an Hoff, y A ndy Bechtolsheim.
Otros apuestan por el siguiente acrónimo, J ust A nother V ague A cronym ("sólo otro
acrónimo ambiguo más"). La hipótesis que suena con más fuerza es que el nombre de
JAVA hace referencia a un tipo de café que se servía en un bar cercano, de ahí que el
icono sea una taza de café desprendiendo vapor. Otra pista pueden ser los 4 primeros
bytes de los archivos .class, bytes que en hexadecimal nos dan lo siguiente 0xCAFEBABE.
Y a pesar de todas estas teorías, parece que el nombre fue sacado de una lista aleatoria.

Lo que Gosling pretendía hacer es implementar una máquina virtual (MV) con una
estructura y lenguaje que fuese similar a la de C++. Entre los meses de junio y julio del
año 1994, tras una enorme sesión de varios días de John Gaga, James Gosling, Patrick
Naughton, Wayne Rosing y Eric Schmidt, el equipo reorientó la plataforma hacia el
entorno web. Previeron que la llegada de Mosaic (un navegador web) haría que internet
se convirtiese en un medio interactivo. Naughton se puso manos a la obra y creo un
prototipo de navegador web llamado "WebRunner", al que más tarde se le conocería con
el nombre de HotJAVA.

Allá por el año 1994 a los altos cargos de Sun se les hizo una demostración de HotJAVA.
La primera versión de JAVA pudo descargarse por primera vez allá por el año 1994, pero
no fue hasta el 23 de mayo del año siguiente cuando se vieron las versiones públicas de
JAVA y HotJAVA, el navegador Web. El acontecimiento fue anunciado por John Gage, el
Director Científico de Sun Microsystems. Además, el acto contó con una sorpresa, Marc
Andreessen, vicepresidente ejecutivo de Netscape, anunció que su navegador soportaría
JAVA El 9 de enero de 1996, SUN fundó el grupo JavaSoft para encargarse de toda la
parte del desarrollo tecnológico. Fue dos semanas más tarde cuando la primera versión
de JAVA fue publicada.

La promesa inicial, si recordamos era aquella que decía "Write Once, Run Anywhere",
haciendo que el lenguaje de programación sea independiente a la plataforma, y
proporcionando una máquina virtual de ejecución para aquellas plataformas más
populares logrando así que el código pudiese ser ejecutado en cualquier plataforma.

Campus Impúlsate | [email protected]


El entorno de ejecución era algo relativamente seguro, así que los principales
navegadores empezaron a dar soporte a la ejecución de applets JAVA dentro de las
propias páginas web.

Java ha experimentado numerosos cambios desde la versión primigenia, JDK 1.0, así
como un gran incremento en el número de clases y de paquetes que forman la biblioteca
base.

Desde la versión J2SE 1.4, todo cambio en el lenguaje ha sido regulada por la "JAVA
Community Process" (JCP), la cual se basa en Java Specification Requests (JSRs) para
proponer cambios futuros a la plataforma. El lenguaje está especificado en la JLS (la
"JAVA Language Specification). Los cambios en los JLS son gestionados en JSR 901.

JDK 1.0 (23 de enero de 1996) — Primer lanzamiento: y comunicado de prensa

JDK 1.1 (19 de febrero de 1997) — Principales adiciones incluidas: comunicado de


prensa

• una reestructuración intensiva del modelo de eventos AWT (Abstract Windowing


Toolkit)
• clases internas (inner classes)
• JavaBeans
• JDBC (Java Database Connectivity), para la integración de bases de datos
• RMI (Remote Method Invocation)

J2SE 1.2 (8 de diciembre de 1998) — Nombre clave Playground. Tanto esta como las
siguientes versiones fueron recogidas bajo la versión Java 2 y el nombre "J2SE" (Java 2
Platform, Standard Edition), reemplazó a JDK para diferenciar la plataforma base de
J2EE (Java 2 Platform, Enterprise Edition) y la J2ME (Java 2 Platform, Micro Edition).
Otras mejoras añadidas incluían:

• la palabra reservada strictfp


• reflexión en la programación
• una API gráfica denominada Swing, que fue integrada en las clases básicas
• la máquina virtual (JVM) de Sun que fue equipada con un compilador JIT (Just
in Time) por primera vez
• Java Plug-in
• Java IDL, una implementación de IDL (Lenguaje de Descripción de Interfaz) para
la interoperabilidad con CORBA
• Colecciones (Collections)

J2SE 1.3 (8 de mayo de 2000) — Nombre clave Kestrel. Los cambios más destacables
fueron:

• la incorporación de la máquina virtual de HotSpot JVM (la cual fue lanzada


inicialmente en abril de 1999, para la JVM de J2SE 1.2)
• RMI fue modificado para que se basase en CORBA
• JavaSound
• se insertó el Java Naming and Directory Interface (JNDI) en el paquete que
contiene las bibliotecas principales (la cual estaba disponible anteriormente
mediante una extensión)
• Java Platform Debugger Architecture (JPDA)

Campus Impúlsate | [email protected]


J2SE 1.4 (6 de febrero de 2002) — Nombre en Clave Merlin. Fue el primer lanzamiento
de la plataforma JAVA desarrollado bajo el control de la comunidad JAVA como JSR 59.
Los cambios más notables fueron:

• La inserción de la palabra reservada assert (Especificado en JSR 41.)


• Expresiones regulares diseñadas al estilo de las expresiones regulares del
lenguaje de programación Perl
• Encadenación de excepciones, la cual permite a una excepción encapsular la
excepción de bajo nivel original.
• non-blocking NIO (New Input/Output) (Especificado en JSR 51.)
• Logging API (Specified in JSR 47.)
• Una API I/O para lectura y escritura de imágenes en formatos JPEG o PNG
• Un "parser" de XML y un procesador XSLT especificado en JSR 5 y JSR 6
• Extensiones criptográficas (JCE, JSSE, JAAS) y seguridad integrada
• Java Web Start incluido (El primer lanzamiento se dio lugar en marzo de 2001
para J2SE 1.3) (Especificado en JSR 56.)

J2SE 5.0 (30 de septiembre de 2004) — Nombre clave: Tiger. (Originalmente numerado
1.5, esta notación aún es usada internamente.) Desarrollado bajo JSR 176, Tiger
incorporó un gran un número de nuevas características

• Plantillas (genéricos) — provee de una conversión de tipos (type safety) durante


el tiempo de compilación para las colecciones y elimina la necesidad de la
mayoría de conversión de tipos (type casting). (Especificado por JSR 14.)
• Metadatos — también conocidos como anotaciones, concede a estructuras del
lenguaje como puedan ser las clases o los métodos, ser etiquetados con algunos
datos adicionales, que puedan ser procesados posteriormente por utilidades de
proceso de metadatos. (Especificado por JSR 175.)
• Autoboxing/unboxing — Conversiones entre tipos primitivos (int) de manera
automática y clases también de envoltura primitiva (Integer). (Especificado por
JSR 201.)
• Enumeraciones — la palabra reservada 'enum' crea un 'typesafe', una lista
ordenada de valores (Dia.LUNES, Dia.Martes...). "Antiguamente", esto solo podía
ser hecho por constantes de tipo int o por clases construidas de forma manual
(enum pattern). (Especificado por JSR 201.)
• Varargs (número de argumentos variable) — El último parámetro puede ser
indicado mediante el tipo de la variable y usar tres puntos para indicar el nombre
de la variable (p.e. void drawtext(String... lines)). Cuando el método sea llamado
con un número indeterminado de parámetros, dichos parámetros serán
almacenados en un array.
• Bucle for mejorado — Se ha extendido la sintaxis para el bucle for, de manera
que sea posible iterar sobre cualquier clase que implemente Iterable, como la
clase estándar Collection de la siguiente forma:

Campus Impúlsate | [email protected]


En este ejemplo el bucle for itera sobre el objeto Iterable widgets, asignando en orden,
cada uno de sus elementos a la variable w, y llamando al método display() de cada uno
de ellas. (Especificado por JSR 201.)

Java SE 6 (11 de diciembre de 2006) — Nombre clave Mustang. Estuvo en desarrollo


bajo la JSR 270. Para esta versión, SUN cambió el nombre "J2SE" por Java SE y eliminó
el ".0" del número de la versión.[3]. Está disponible en http://java.sun.com/javase/6/.
Los cambios más destacables de esta versión son:

• Incorpora un nuevo marco de trabajo y APIs que hacen posible la combinación


de JAVA con otros lenguajes de programación como puedan ser PHP, Python,
Ruby y JavaScript.
• También incorpora el motor Rhino, de Mozilla, una implementación de JavaScript
dentro de Java.
• Incluye por completo un cliente de Servicios Wev y soporta las últimas
especificaciones para los servicios web, como puedan ser JAX-WS 2.0, JAXB 2.0,
STAX y JAXP.
• Mejoras en la interfaz gráfica y en el rendimiento en general.

Java SE 7 — Nombre clave Dolphin. Aún se encontraba en las primeras etapas de


planificación allá por el año 2006. Su lanzamiento definitivo fue en julio de 2011.

• XML soportado en el propio lenguaje.


• Un nuevo concepto de "superpaquete".
• Soporte para closures.
• Anotaciones estándares para detectar fallos del software.

No oficiales:

• NIO2.
• Java Module System.
• Java Kernel.
• Una nueva API para poder hacer usos de Días y Fechas, la cual es un reemplazo
de las antiguas clases Date y Calendar.
• Posibilidad de operar con clases BigDecimal usando operandos.

Java SE 8 — fue lanzada en marzo de 2014. Cabe resaltar:

• Incorpora de forma completa la librería JavaFX.


• Mejoras en seguridad varias.
• Mejoras en la concurrencia.
• Añade funcionalidad para programación funcional mediante expresiones
Lambda.
• Mejora la integración de JavaScript.
• Nuevas API para el manejo de las fechas y del tiempo (date - time).

Java SE 9 — fue lanzada en 2017. Cabe resaltar:

• Modularización del JDK bajo Project Jigsaw (Sistema de módulos de plataforma


Java).
• Java Shell (un Java REPL).
• Compilación anticipada.

Campus Impúlsate | [email protected]


• Catálogos XML.
• Más actualizaciones de concurrencia. Incluye una implementación de Java de
Reactive Streams, que incluye una nueva clase de flujo que incluye las interfaces
proporcionadas previamente por Reactive Streams.
• Variable handles: define un medio estándar para invocar los equivalentes de
varias operaciones java.util.concurrent.atomic y sun.misc.Unsafe.
• Java Linker: crea una herramienta que puede ensamblar y optimizar un conjunto
de módulos y sus dependencias en una imagen personalizada en tiempo de
ejecución. De manera efectiva, permite producir un ejecutable totalmente
utilizable, incluyendo la JVM para ejecutarlo.
• JavaDB se eliminó de JDK.
• Gráficos HiDPI: escala y tamaño automáticos.

Java SE 10 — se lanzó el 20 de marzo de 2018, con doce funciones nuevas confirmadas.


[324] Entre estas características se encuentran:

• Inferencia de tipo de variable local.


• Compilador JIT experimental basado en Java. Esta es la integración del
compilador dinámico Graal para la plataforma Linux x64.
• Intercambio de datos de clase de aplicación. Esto permite que las clases de
aplicaciones se coloquen en el archivo compartido para reducir el inicio y la
huella de las aplicaciones Java.
• Versiones basadas en tiempo.
• GC completo paralelo para G.
• Interfaz recolector de basura.
• Extensiones adicionales de etiquetas de idioma Unicode.
• Certificados de raíz.
• Apretones de manos locales.
• Asignación de pila en dispositivos de memoria alternativos.
• Eliminar la herramienta de generación de encabezados nativos - javah
• JEP 296: Consolidar el bosque JDK en un único repositorio.

Java SE 11 — se lanzó en septiembre de 2018 y la versión está actualmente abierta para


corregir errores. Entre otros, Java 11 incluye una serie de características nuevas, tales
como:

• Constantes de archivo de clase dinámicas.


• Epsilon: un recolector de basura sin operación.
• sintaxis de variable local para parámetros lambda.
• Perfil de pila de baja sobrecarga.
• cliente HTTP (estándar).
• Seguridad de la capa de transporte (TLS) 1.3.
• Registrador de vuelo.
• ZGC: un recolector de basura escalable de baja latencia.
• Los módulos JavaFX, Java EE y CORBA se han eliminado de JDK.
• Desaprobó el motor de JavaScript de Nashorn.
• Compatibilidad con Unicode 10.0.0 (mientras que la versión actual es Unicode
11.0.0, solo está en Java 12).

Campus Impúlsate | [email protected]


Java SE 11 — se lanzó en septiembre de 2018

La Especificación de la Máquina Virtual Java la define como:

JDK 12 — se lanzó el 19 de marzo de 2019. Entre otros, Java 12 incluye una serie de
características nuevas, tales como:

• Shenandoah: Un recolector de basura de bajo tiempo de pausa (Experimental)


• Microbenchmark Suite.
• Cambiar expresiones (vista previa).
• API de constantes JVM.
• un puerto AArch64, no dos.
• Archivos CDS predeterminados.
• Colecciones Abortables Mixtas para G1.
• Devolver rápidamente la memoria comprometida no utilizada de G1.

Una máquina imaginaria implementada mediante la emulación por software en una


máquina real. El código para la máquina virtual Java se almacena en archivos .class,
cada uno de los cuales contiene, al menos, el código para una clase pública.

La especificación de la máquina virtual java proporciona las especificaciones de


hardware para las que se compila toda la tecnología java. Esta especificación permite
al software en java ser independiente de la plataforma ya que la compilación se hace
para una máquina genérica conocida como la máquina virtual java (JVM). Esta puede
ser emulada por software para poder ser ejecutada en los diferentes sistemas
informáticos existentes, o bien ser implementada en hardware.

A partir del código fuente el compilador genera bytecodes. Estos bytecodes son
instrucciones de código máquina para la JVM. Cada intérprete de java tiene una
implementación de la JVM.

La especificación de la JVM proporciona definiciones muy concretas para la


implementación de:

Características de java
Robusto:

Java realiza verificaciones en busca de problemas tanto en tiempo de compilación


como en tiempo de ejecución. En tiempo de compilación no tiene ningún misterio porque
todos los lenguajes realizan esas verificaciones, sin embargo, en tiempo de ejecución,
la JVM, que realiza la interpretación de los bytecodes, detecta cuando existe algún
problema en la ejecución del programa, y lanza excepciones que pueden ser recogidas
por el programador con el propósito de recuperarse de dichos errores.

Arquitectura neutral (multiplataforma):

Gracias a que la compilación se realiza a un código objeto independiente de la


arquitectura de la máquina (bytecodes), tan sólo necesitamos utilizar el intérprete
adecuado para que nuestro programa funcione sobre cualquier plataforma. El lema de
Sun es "escribir una vez, ejecutar en cualquier parte".

Seguro:

Campus Impúlsate | [email protected]


Como toda la ejecución la realiza la JVM, los programas Java pueden ser sometidos a
muchas comprobaciones antes de ejecutarse en la máquina. En concreto:

• El código se pasa a través de un verificador de ByteCodes que comprueba el


formato de los fragmentos de código y detecta fragmentos de código ilegal
(código que falsea punteros, violas derechos de acceso sobre objetos, etc.).
• El cargador de clases separa el espacio de nombres del sistema de ficheros local
del de los recursos procedentes de la red. Esto limita cualquier aplicación del
tipo Caballo de Troya, ya que las clases se buscan primero entre las locales y
luego entre las procedentes del exterior.
• Respecto a la seguridad del código fuente, el propio JDK proporciona un
desensamblador de ByteCodes, que hace que cualquier programa pueda ser
convertido a código fuente a partir de sus bytecodes. Utilizando javap no se
obtiene el código fuente original, aunque si desmonta el programa mostrando su
estructura. Este problema de seguridad del código fuente es algo todavía
pendiente de subsanar.

Portable:

Más allá de la portabilidad básica por ser de arquitectura independiente, Java


implementa otros estándares de portabilidad para facilitar el desarrollo.

Los enteros son de 32 bits en complemento a 2.

Java construye sus interfaces de usuario a través de un sistema abstracto de ventanas


de forma que éstas puedan ser implantadas en entornos UNIX, Mac o Pc.

Desarrollo con Java:

Para poder desarrollar software con Java necesitamos una serie de herramientas que
nos proporciona Sun a través de su JDK (Java Development Kit).

Al igual que el lenguaje natural que utilizamos para comunicarnos, ya sea de forma oral
o por escrito, cualquier lenguaje de programación dispone de unos elementos y reglas
que deben conocerse a la hora de programar.

Los elementos del lenguaje natural nos permiten designar cosas (nombres), expresar
cualidades de esas cosas (adjetivos), expresar acciones (verbos), etc.

Las reglas sintácticas (estructura) y semánticas (significado) permiten el entendimiento


entre las partes que forman la comunicación.

En los lenguajes de programación también encontramos unas reglas sintácticas que


debemos respetar a la hora de confeccionar los programas y una semántica encargada
de resolver el problema que queremos programar.

Elementos y reglas sintácticas de los lenguajes de programación:

Aunque todos los conceptos que aprenderemos a continuación aparecen en todos los
lenguajes de programación existen diferencias en la implementación en cada uno de
ellos lo que obliga a un estudio individual en cada uno de ellos.

Comentarios en los programas:

Campus Impúlsate | [email protected]


Un aspecto importante a la hora de confeccionar un programa es comentar lo más
detalladamente posible lo que significa cada una de las órdenes que forman parte del
programa, con el propósito de poder recordar en un futuro la función que realiza cada
una de ellas, y facilitar su estudio a personas ajenas al programa.

Identificadores:

En todo lenguaje de programación surge la necesidad de utilizar una serie de elementos


que debemos designar con algún nombre, por ejemplo:

ELEMENTO DESCRIPCIÓN
Variables - Elementos utilizados para referenciar posiciones de memoria dónde
podremos almacenar datos necesarios para el programa.
Funciones - Elementos utilizados para referenciar posiciones de memoria dónde
reside el código del programa.
Objetos - Elementos que encapsulan variables (propiedades) y funciones
(métodos) de manera que resulta más sencillo modelar los problemas
que queremos resolver simplificando el diseño de programas
complejos.
etc. - Conforme avancemos iremos conociendo más elementos de los
lenguajes de programación.

A la hora de asignar nombre a todos estos elementos hay que seguir unas reglas.

Tipos de datos básicos:

El modelo mental más sencillo que se puede tener de una aplicación informática es el
de una caja negra que recibe unos datos de entrada, los procesa y entrega unos datos
de salida representados de alguna manera.

Estos datos de entrada, los cuáles deben ser albergados en memoria y referenciados
mediante alguna variable, pueden ser de diferente naturaleza (numéricos,
alfanuméricos, etc.).

Cada lenguaje de programación dispone de unos tipos de datos básicos a los cuáles
nos tenemos que amoldar a la hora de realizar el análisis de los datos que necesitamos
en nuestra aplicación.

Variables:

Este elemento juega un papel muy importante en el programa porque es el mecanismo


que pone a nuestra disposición el lenguaje de programación para gestionar de una
manera sencilla los datos de la aplicación.

Al declarar una variable en el programa estamos reservando una zona de memoria para
posteriormente albergar un dato. Existen lenguajes que necesitan que especifiquemos
el tipo de dato que se va a albergar (java) y otros que no lo necesitan (javascript).

Al asignar un valor a la variable lo que estamos haciendo es almacenar el dato en la


posición de memoria que se reservó para dicha variable.

Campus Impúlsate | [email protected]


En todo momento tenemos que tener presente que al usar la variable realmente estamos
usando el dato al que representa.

Operadores:

Una de las primeras aplicaciones de los ordenadores fue el cálculo de matemático y,


aunque ahora ha pasado a un segundo plano, los lenguajes de programación ofrecen
una serie de elementos que permiten realizar operaciones con los datos.

Estas operaciones no sólo se limitan a operaciones aritméticas. Disponemos también


de operaciones lógicas, comparaciones, etc.

Sentencias de control:

Sin embargo, la característica que confiere al ordenador su potencia es la capacidad de


procesamiento de la que dispone.

Aunque esto nos pueda asustar, el tipo de procesamiento que puede realizar es muy
básico, limitándose a:

Tomar decisiones sobre la ejecución o no de determinadas tareas en base al


cumplimiento o no de una o varias condiciones (sentencias de decisión). En dichas
condiciones siempre estarán implicados datos (o si se quiere, sus representantes las
variables).

Alterar el flujo de ejecución normal del código del programa (sentencias de salto o
bucles). También estas alteraciones estarán controladas por variables.

La combinación adecuada de este tipo de sentencias es la que definirá la estructura que


resuelve un determinado problema.

Almacenamiento de datos mediante Arrays:

Hemos visto el uso de variables como mecanismo básico para almacenar y acceder a
datos en memoria. Sin embargo, en la mayoría de aplicaciones este tipo de
almacenamiento de información se queda corto por ser demasiado simple y
necesitamos a sistemas de almacenamiento más complejos, pero también más
potentes.

Uno de estos sistemas, que aparece en todos los lenguajes de programación, es el de


los Arrays.

Excepciones:

Todos los lenguajes de programación avisan de los errores que cometamos en tiempo
de compilación, pero pocos son los que han sido diseñados para seguir avisando de
posibles errores en tiempo de ejecución. Las aplicaciones Java, gracias a que se
ejecutan bajo la supervisión de la máquina virtual (JVM), están siendo controladas
constantemente. En caso de que ocurra algún error de ejecución, se lanza una excepción
que puede ser recogida y tratada por el programador en su aplicación. De esta manera,
lo que antes solía terminar en una ejecución anormal del programa, con java puede ser
resuelto.

Campus Impúlsate | [email protected]


Objetos:

Java es un lenguaje de programación orientado a objetos. La importancia de este tema


es tal que le dedicamos el siguiente capítulo entero.

1.2. Clases
Las diferentes tecnologías de programación se diferencian en la manera que ofrecen de
estructurar los datos y el código que forman una aplicación.

A la hora de plantear el análisis del problema que se quiere resolver por software, todas
las tecnologías han optado por dividir dicho problema en parte más pequeñas. La
estrategia a seguir es conseguir una estructura en la que cada una de esas partes realice
una tarea única e indivisible, coordinadas por una parte principal que obtiene la
información de lo que hay que hacer de su interacción con el usuario. En la actualidad
esta interacción se realiza a través de un entorno gráfico y las órdenes se generan
mediante eventos.

En los lenguajes procedimentales, orientados a funciones, la estructura se realiza


tomando como referencia el código. Cada una de las partes se denomina subrutina,
procedimiento o función dependiendo del lenguaje en el que nos encontremos, cada una
se ejecuta teniendo solo en cuenta los parámetros de entrada sin modificar nada externo
a ella.

En los lenguajes imperativos, orientados a objetos, la estructura se realiza tomando


como referencia los datos. Los datos se agrupan en función de su naturaleza en
componentes denominados objetos. Para definir qué datos puede contener un objeto y
sus acciones utilizamos plantilla que denominamos clase la cual define sus propiedades
(datos) y métodos (acciones).

Un objeto, como en la vida real, posee una serie de propiedades. Por ejemplo, digamos
que queremos crear un sistema para almacenar y organizar expedientes urbanísticos de
obra. En papel un expediente contiene los datos de la persona e información relativa a
su solicitud. Dicha persona puede tener asociados una serie de datos como nombre,
apellidos, DNI, dirección, teléfono, etc.

Para el diseño de un sistema debemos identificar los datos y agruparlos en objetos,


también necesitamos identificar qué acciones puede realizar un objeto y como afectan
a otros. En este ejemplo hemos partido de un conjunto de datos de un formulario para
dividirlos en dos objetos cada uno responsable de gestionar dichos datos. Como hemos
comentado una clase define un objeto, en esta se indican el nombre de cada propiedad
y de qué tipo son como por ejemplo texto, numérico u otro objeto como en este caso la
persona solicitante. También se definen que acciones realiza y estas pueden modificar
los datos de dicha clase.

Una clase es una entidad que determina cómo se comportará un objeto y qué contendrá
el objeto. En otras palabras, es un plan o un conjunto de instrucciones para construir un
tipo específico de objeto.

Campus Impúlsate | [email protected]


1.3. Creación de una clase.

En Java una clase se suele representar con la siguiente estructura:ç

public class NombreClase


{
// Esto es un comentario
/*
Esto es un comentario con múltiples líneas
*/
// Definición de propiedades --> Características del elemento que
describimos con la clase.
public int propiedadPublica; //<- Puede acceder cualquiera
private int propiedadPrivada; //<- Solo puede la clase
protected int propiedadProtegida; //<- La clase y las que hereden
de ella
static int propiedadProtegida; //<- Propiedad estática accesible
por cualquiera
// Definición de los métodos --> Comportamiento y funcionalidades
del elemento.

public void hacerAlgo(){//<-función pública que devuelve nada


//codigo de la funcion
}
public int devuelveAlgo(){//<-función pública que devuelve un
entero
return this.propiedadPrivada;//Devolvemos una propiedad
}

Como se puede ver en Java las clases se definen con la palabra class seguido del
nombre por la que queremos identificarla. Vamos a explicar una serie de palabras
usadas junto a las propiedades y métodos, estas controlan de qué manera se accede a
la propiedad que acompañan:

• public: indica que la propiedad es accesible desde fuera, por ejemplo podemos
acceder a propiedades de un objeto desde los métodos de clase pero también
desde fuera de la clase usando la variable del objeto y un punto, por ejemplo
perro.colorPelo.

Campus Impúlsate | [email protected]


• protected: esta está relacionada con la herencia de objetos, una clase que herede
de otra puede acceder a esa propiedad, pero no desde fuera de la clase padre.
• private: las propiedades con private solo son accesibles desde la clase en la que
se define, no pueden acceder clases que heredan ni desde fuera.
• static: es una propiedad compartida entre todos los objetos creados a partir de
la clase, además es accesible a través de la propia clase sin requerir un objeto.
Se puede usar junto a public, protected y private.
• final: la propiedad no puede ser alterada, en el caso de un tipo primitivo el valor
no puede cambiar, en cambio sí posee una referencia a un objeto este sí puede
ser alterado, pero no se permitirá que cambie la referencia a otro objeto. Se
puede utilizar junto con public, protected y private.

Un método o también llamado función se define de manera similar a las propiedades,


tiene limitaciones en el acceso e incluso puede ser static, según el valor u objeto que
devuelvan se indica con un nombre anterior al de la función, en caso de que no devuelvan
nada se indica con void.

Hay que tener en cuenta de que la variable de un objeto no es el objeto en sí, sino una
referencia, en caso de que una función devuelva una propiedad privada con referencia a
un objeto nos arriesgamos de que más adelante el objeto pueda ser modificado y dichas
modificaciones afecten de manera inesperada al funcionamiento de otros
componentes. Para evitar la modificación de un objeto referenciado por una propiedad
privada se debe realizar una copia de dicho objeto y devolverlo, de esta manera cualquier
modificación realizada fuera de la clase no interferirá.

En el segmento de código anterior, hemos hecho uso de datos primitivos y de tipos, en


Java toda variable tiene definido un tipo. Un tipo se puede entender como una
identificación de que dato tiene la variable, una variable puede hacer referencia a un
objeto por lo que su tipo es el nombre de dicha clase. Sin embargo, no hay solo objetos
en Java, una variable también puede contener un valor de un tipo concreto, a estos tipos
los denominamos primitivos. Java incluye ocho tipos primitivos:

• byte: es un número entero que en memoria ocupa 8 bits. Sus valores van de -128
a 127.
• short: es un entero de 16 bits. Su valor mínimo es -32,768 y el máximo 32,767.
• int: es un entero de 32 bits. Su valor mínimo es -2,147,483,648 y el máximo
2,147,483,647 (inclusive). Es el tipo más usado para números enteros a menos
que haya una razón para usar otro como por ejemplo el ahorro de memoria.
• long: es un entero de 64 bits. Su valor va de -9,223,372,036,854,775,808 a
9,223,372,036,854,775,807. Obviamente se utiliza cuando int no alcanza el valor
que se requiere.
• float: es un dato en coma flotante y precisión simple. No entraremos en detalle
sobre cómo funciona, pero se utiliza para almacenar valores decimales que no
requieran gran precisión ya que pueden devolver producir cierto grado de error
en la parte decimal.
• double: dato en coma flotante de 64 bits y precisión doble. Similar a float pero
admite un mayor rango de valores, es comúnmente utilizado al tratar con valores
decimales.
• boolean: solo tiene dos valores posibles true (verdadero) y false (falso).
• char: contiene un solo carácter Unicode de 16 bits.

Campus Impúlsate | [email protected]


A Java se le considera un lenguaje fuertemente tipado ya que obliga a indicar el tipo de
cada variable, en el caso de otros lenguajes como PHP se pueden usar tipos, pero no es
obligatorio. Aunque puede suponer una carga de trabajo adicional según la situación el
uso de tipos ayuda a la prevención de errores.

En el siguiente ejemplo podemos ver un fichero en java completo que contiene la


definición de una clase, la clase definida tiene el nombre Coche:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Coche {


private boolean estado = false;
private int velocidad = 0;
public final static int VMAXIMA = 120;

public static void menu() {

System.out.println("1.- Montar en el coche");


System.out.println("2.- Comenzar");
System.out.println("3.- Parar");
System.out.println("4.- Salir del coche");
System.out.println("");
System.out.println("Introduzca una opción");

public void montar() {


if (estado == false) {
System.out.println("Ya estás encima del coche.");
estado = true;
}
else {
System.out.println("Ya estabas arriba, no intentes subir otra
vez.");
}
menu();
}

public void comenzar() {


if (estado == false) {
System.out.println("Primero sube al coche");
}
else if (velocidad == VMAXIMA) {
System.out.println("Ya no puedes acelerar más");

}
else {
++velocidad;

Campus Impúlsate | [email protected]


System.out.println("Velocidad actual= " + velocidad);
}
menu();
}

public void parar() {


if (velocidad == 0) {
System.out.println("Si estás parado porque frenas");
}
else {
System.out.println("El frenado se realiza de golpe");
velocidad = 0;
}
menu();

public void salirCoche() {


if (estado == false) {
System.out.println("No te has subido y ya te bajas");
}
else if (velocidad != 0) {
System.out.println("Primero frena y luego baja");
}
else {
System.out.println("Acabas de bajar del coche.");
}
menu();
}

public int getVelocidad(){


return this.velocidad;
}

public void setVelocidad(int v){


if(Coche.VMAXIMA > v){
this.velocidad = v;
}
else{
this.velocidad = v;
}
}
}

Campus Impúlsate | [email protected]


Como se puede observar hay una propiedad llama VMAXIMA establecida como publica,
estática y final esto quiere decir que puede ser accedida desde fuera de la clase, esta
compartida entre todas las instancias y que su valor es final, es decir no podrá ser
modificado. Entendemos que la velocidad máxima es el tope de velocidad que todas las
instancias de Coche soportan. No nos interesa que se supere la velocidad máxima
establecida en el vehículo por lo que la declaramos privada y para modificarla por
cualquiera fuera de nuestra clase es necesario pasar por la función setVelocidad.

En el segmento de código anterior se ha hecho uso de la declaración import. Antes de


nada, expliquemos que es un paquete en Java:

En Java un paquete se le conoce como un conjunto de clases y otros paquetes, estos


siguen una estructura jerárquica en carpetas. En la siguiente imagen se puede ver el
directorio de un paquete llamado "ssh_tunnel" que a su vez contiene un paquete
denominado "utils". Normalmente en un paquete se agrupan las clases de una misma
aplicación, organización, sistema o que comparten una serie de funciones similares.
(Figura 1).

Figura 1 La imagen muestra una captura de pantalla de un paquete Java con ficheros de clases y un directorio
que representa un subpaquete

Para hacer uso de clases en paquetes externos tenemos que hacer uso de su nombre
en una sentencia import o si es un uso puntual podemos usar el nombre del paquete
seguido de la clase como se ve en el siguiente ejemplo:

frutas.citricos.Limon naranja = new frutas.citricos.Limon();//Usando


el nombre completo
import frutas.citricos.Limon; //importamos la clase Limón
import frutas.citricos.*; //lo importamos todo

Campus Impúlsate | [email protected]


1.4. Objetos
En ingeniería de software, SOLID (Single responsibility, Open-closed, Liskov
substitution, Interface segregation and Dependency inversion) es un acrónimo
mnemónico introducido por Robert C. Martin a principios de la década de los 2000 que
representan cinco principios básicos de la programación orientada a objetos y el diseño.
Cuando estos principios son aplicados como un conjunto, es más probable que un
desarrollador cree un sistema que a lo largo del tiempo sea fácil de mantener y de
ampliar. Los principios SOLID son guías que podemos usar en el desarrollo de un
software, que nos ayudará a eliminar el código sucio provocando que el programador
tenga que refactorizar el código fuente hasta que sea legible. Debería de ser utilizado en
el desarrollo guiado por pruebas o TDD, y además forma parte de la estrategia global del
desarrollo ágil de software y desarrollo adaptativo de software.

El principio de responsabilidad única indica que cada módulo o clase de contar con una
responsabilidad sobre una sola parte de la funcionalidad por el software y esta
responsabilidad debe estar encapsulada en su totalidad por la clase. Todos sus
servicios deben estar estrechamente alineados con esa responsabilidad. Robert C.
Martin expresa dicho principio de la siguiente forma: Una clase debe tener solo una razón
para cambiar.

El principio de abierto/cerrado establece que «una entidad de software (clase, módulo,


función, etc.) debe quedarse abierta para su extensión, pero cerrada para su
modificación». En otras palabras, se debe de poder ampliar el comportamiento de la
entidad sin tener que modificar su código fuente.

abierto/cerrado es utilizado de dos maneras: las dos se basan en la herencia para poder
resolver el aparente dilema, pero tanto como sus objetos, técnicas y sus resultados son
diferentes.

Principio de sustitución de Liskov es un principio de la programación orientada a objetos


y puede definirse como: Es posible usar como su padre cada clase que hereda de otra
sin la necesidad de conocer las diferencias entre ellas.

En un lenguaje más formal: si S es un subtipo de T, entonces todos los objetos de tipo T


en un programa podrán ser sustituidos por objetos de tipo S (en otras palabras, los
objetos de tipo S pueden sustituir a los de tipo T), sin cambiar ninguna de las
propiedades deseables del programa (como pueda ser la corrección, la tarea que realiza,
etc.) De una manera más formal, el Principio de Sustitución de Liskov (LSP), define de
manera particular una relación de subtipificación, conocida como tipificación del
comportamiento, la cual fue introducida inicialmente por Barbara Liskov en una
conferencia allá por el año 1987 llamada "LA Abstracción de Datos y Jerarquía". Está
más referida a una relación de tipo semántico que a una de tipo sintáctico, ya que tan
solo tiene la intención de garantizar la interoperabilidad semántica de tipos dentro de
una jerarquía, los tipos de objeto en particular. Jeannette Wing y Liskov crearon el
principio de manera conjunta en un artículo en 1994 que dicta lo siguiente:

Sea Φ(𝑥) una propiedad comprobable acerca de los objetivos 𝑥 de tipo 𝑇. entonces
Φ(𝑦) debe ser verdad para los objetos y del tipo 𝑆 donde 𝑆 es un subtipo de 𝑇

Campus Impúlsate | [email protected]


El principio de segregación de la interfaz (ISP, por sus siglas en inglés) establece que los
clientes de un programa dado sólo deberían conocer de éste aquellos métodos que
realmente usan, y no aquellos que no necesitan usar. El ISP es aplicado a una interfaz
amplia y compleja para así seccionarse en otras más pequeñas y específicas, de tal
forma que el cliente use tan solo la que necesite, pudiendo así ignorar al resto. A este
tipo de interfaces reducidas se les llama "interfaces de rol".

El ISP fue concebido para mantener a un sistema desacoplado de los otros sistemas de
los que depende, y que así resulte más fácil una refactorización, modificarlo y
redesplegarlo. El ISP es uno de los cinco principios S.O.L.I.D. del Diseño Orientado a
Objetos, similar al Principio de Alta Cohesión de GRASP.

El principio de inversión de dependencias está compuesto por los siguientes dos puntos:

A: Los módulos de alto nivel no deberían depender de los de bajo nivel. Los dos
deberían de depender de las abstracciones.

B: Ninguna abstracción debería depender de ningún detalle. Son los propios


detalles los que deberían de depender de las abstracciones.

En el paradigma de la orientación a objetos, lo más normal es tener una jerarquía de


objetos definida, porque los objetos de más alto nivel son los que suelen incluir a los de
bajo nivel.

Un bosque contiene árboles, que a su vez contienen hojas, que contienen células…

Por eso se eligió la palabra “inversión”, porque rompe con esta dinámica.

Los que en principio se pretende es que no exista una necesidad de dependencia entre
unos módulos y otros, sino que dependan de abstracciones. De esta forma, nuestros
módulos pueden ser más fácilmente reutilizables.

Como ya hemos visto un objeto es una representación abstracta compuesto por


propiedades también llamados atributos y una serie de métodos o funciones para
manipular dichas propiedades.

Podemos considerar las Clases como plantillas de objetos, definen que propiedades
tienen y sus métodos, instancia una clase da como resultado un nuevo objeto. En Java
las propiedades de un objeto pueden ser de tipo primitivo o referencias a otros objetos,
en cuanto a esto último entendemos que un objeto puede estar compuesto por otros,
por ejemplo, una bicicleta está compuesta por un pedal, manillar, ruedas etc. Cada
objeto de una clase puede tener un valor propio en cada propiedad, aunque comparten
la misma funcionalidad, cada silla puede ser de un color distinto pero el hecho de que
sirve para sentarse no cambia.

Crear un objeto en Java es simple:

//Un coche rojo con cinco plazas


Coche miCoche = new Coche("rojo", 5);

Campus Impúlsate | [email protected]


Declaramos un variable con el nombre de la clase como tipo y la instancia con new. Al
hacer esto se reserva memoria para el objeto y la variable hace referencia a este, en el
caso de realizar:

//¿Estaré copiando el objeto?


Coche miPropioCoche = miCoche;

Lo que hacemos es asignar el mismo objeto a las variables miCoche y miPropioCoche,


cualquier modificación como miCoche.setColor("azul") afectara a ambos. Si lo que
queremos es una copia hay algunas soluciones en bibliotecas de terceros, pero lo más
seguro es que el desarrollador implemente su propia función para crear duplicados. Por
ejemplo, a través del método clone o un constructor con un objeto de la misma clase
como parámetro y copiar las primitivas, para propiedades que son referencias a objetos
también habría que duplicarlos:

public class Coche{


//.....
public Coche(Coche original){
this.color = original.color;
this.plazas = original.plazas;
//......
}
public Coche clone(){
//Ya he creado un constructor de copia, me puedo ahorrar
repetir el codigo
Coche nuevo = new Coche(this);
return nuevo;
}

A lo largo del módulo veremos el uso de objetos definidos por la clase String, esta es
una clase definida en Java y que permite almacenar y trabajar con cadenas de texto. La
peculiaridad de esta clase es que no permite la modificación del texto que almacena,
métodos como split crean un array con dos nuevas instancias de String cada una con
una copia de un fragmento del texto original. Por ello no hay porque preocuparse de
generar copias de propiedades privadas de este objeto ya que por diseño impide su
alteración. El texto englobado por comillas dobles es considerado por el compilador de
Java como un objeto String.

Si no estás familiarizado con el concepto de array en Java es un contenedor de objetos,


es decir almacena un número fijo de objetos de un tipo concreto. Su capacidad se define
al ser creado:

Coche[] referenciaArray;
// memoria para 15 coches
referenciaArray = new Coche[15];

Campus Impúlsate | [email protected]


1.5. Ejemplo Práctico con Objetos.
A continuación, mostraremos un ejemplo práctico de crear un programa básico en Java.
Sera necesario tener instalado algún kit de desarrollo de java, puede encontrarlo
introduciendo en cualquier buscador la palabra JDK (Java Development Kit). El JDK
contiene las herramientas necesarias para la compilación del código fuente y su
ejecución. El compilador incluido esta desarrollado para usarlo a través de una terminal,
en este caso usaremos la consola de comandos de Windows (CMD) y comando se
denomina javac.

Asegúrese de descargar la versión apropiada del JDK para su procesador y sistema


operativo, previamente aceptando los términos de la licencia. Una vez descargado la
instalación se sigue como cualquier otro instalador. (Descargue el JDK aquí).

Figura 2 Se muestra una parte de la página de descarga del kit de desarrollo en Java señalando que se deben aceptar
los términos de uso y descargar la versión apropiada a la arquitectura del procesador y sistema operativo, en este
caso Windows 64 bits.

Como se ha explicado para la creación de un objeto necesitamos de una plantilla


denominada clase. Cada clase define que propiedades puede tener un objeto y sus
métodos.

A cada clase se le asigna un nombre para identificarla y utilizarla durante el desarrollo


de una aplicación, en el siguiente ejemplo tenemos la clase Factura, la creación de un
objeto a partir de una clase lo denominamos instanciación, todo objeto creado a partir
de Factura lo llamaríamos instancia de Factura.

Vamos a mostrar un ejemplo de clase y su utilización. Crearemos una nueva clase


llamada Factura. Una factura está compuesta por un nombre de titular, un concepto, un
precio, el iva y el total de la factura.

Campus Impúlsate | [email protected]


public class Factura{
public String NombreTitular;
public String ConceptoFactura;
public double Precio;
public double Total;
public double Iva;
}

Hemos creado una clase en la que podemos almacenar una serie de datos primitivos en
su conjunto. Dicha clase contiene una serie de miembros que almacenará cada objeto
creado a partir de la clase Factura. En el ejemplo podemos observar variables de tipo
String, String es una clase incluida en Java para representar una cadena de texto, dicho
texto es inmutable, es decir no se puede alterar, por ello la clase String implementa una
serie de métodos para operaciones como la concatenación y división de texto que
devuelven nuevas instancias.

Cada objeto Factura, es decir cada instancia de la clase, tiene su propia copia de las
variables miembro. Como hemos mencionado las variables propias de una clase
(propiedades) pueden ser de tipos primitivos (boolean, int, long, double...) o referencias
a objetos de otra clase (composición).

Campus Impúlsate | [email protected]


En nuestro ejemplo, hemos creado cinco variables miembro de la clase factura, dichas
variables miembro son elementos que pertenecen a la clase Factura y sólo pueden ser
utilizadas por objetos de la clase Factura. Cada Factura que creemos tendrá unos
valores diferentes para cada miembro.

public class UtilizacionFactura{

public static void main(String[] args){


Factura f1 = new Factura();
f1.NombreTitular = "Adrian Ramos";
f1.ConceptoFactura = "IPad";
f1.Precio = 540;
f1.Iva = 30;
f1.Total = 570

System.out.println("Datos de la factura numero 1");


System.out.println("Nombre Titular: " + f1.NombreTitular);
System.out.println("Concepto Factura: " + f1.ConceptoFactura);
System.out.println("Precio: " + f1.Precio);
System.out.println("Iva: " + f1.Iva);
System.out.println("Total: " + f1.Total);
System.out.println("-------------------------------------");

Factura f2 = new Factura();


f2.NombreTitular = "Lucia Serrano";
f2.ConceptoFactura = "PSP";
f2.Precio = 169;
f2.Iva = 15;
f2.Total = 184;

System.out.println("Datos de la factura numero 2");


System.out.println("Nombre Titular: " + f2.NombreTitular);
System.out.println("Concepto Factura: " + f2.ConceptoFactura);
System.out.println("Precio: " + f2.Precio);
System.out.println("Iva: " + f2.Iva);
System.out.println("Total: " + f2.Total);
}
}

En este ejemplo mostramos otra clase denominada UtilizacionFactura, esta clase


no se ha creado con el fin de crear objetos sino para la ejecución de código, que está
contenido en el método main.

Como podemos comprobar, cada objeto referenciado de la clase factura contiene unos
datos diferentes para cada elemento. Es decir, cada miembro de la instancia de Factura
almacena unos datos diferentes en cada objeto.

Para compilar el programa partimos de dos ficheros con extensión .java, es importante
utilizar un editor de texto plano como el Bloc de Notas o Notepad++. Cada fichero debe
tener el nombre de la clase, en este ejemplo deben resultar como: Factura.java y

Campus Impúlsate | [email protected]


UtilizacionFactura.java. Para mayor facilidad las hemos creado en una carpeta en
la unidad C:\, para compilar nuestro programa usamos el comando javac (Figura 3):

Figura 3 Ejemplo simple del comando javac para la compilación de ficheros .java javac *.java

Si lo has compilado te habrás dado cuenta de una pequeña errata en nuestro código,
para ser precisos en la línea 9 de UtilizacionFactura.java donde pone "f1.Total
= 570" falta un punto y coma al final (Figura 4):

Figura 4 Ejemplo de un error de sintaxis mostrado por el comando javac. En este caso la linea 9 de
UtilizacionFactura.java le falta un punto y coma al final.

En el comando mostrado compilamos todos los ficheros *.java de la carpeta dando


como resultado ficheros .class que contienes el bytecode de cada clase, para
ejecutar nuestro programa debemos utilizar el nombre de la clase que contiene la
función main (Figura 5):

Figura 5 Se muestra la ejecución de un programa compilado por javac con el comando java -cp . UtilizacionFactura.
Imprime en pantalla los datos de dos objetos factura distintos.

Como mencionamos cada objeto Factura tenía un contenido propio y este se ha


imprimido (System.out.println) en la salida del programa.

Campus Impúlsate | [email protected]


1.6. Ejemplo Práctico con Objetos II.
Para hacer referencia a los objetos que pertenecen a la clase sobre la que estamos
escribiendo se utiliza la palabra clave this. Dicha palabra hace referencia a cualquier
elemento declarado en la clase.

public class Factura


{
public String NombreTitular;
public String ConceptoFactura;
public double Precio;
public double Total;
public double Iva;

//CONSTRUCTOR DE FACTURA
public Factura()
{
//VAMOS A INICIALIZAR LOS MIEMBROS DE LA CLASE
this.NombreTitular = "sin titular";
this.ConceptoFactura = "sin concepto";
this.Precio = 0.0;
this.Iva = 0.0;
this.Total = 0.0;
}
}

Podemos observar un método con el mismo nombre que la clase Factura. Este método
lo denominamos constructor y será llamado cada vez que se cree (instanciar) un objeto,
su principal función es asignar un valor a cada variable, eso puede incluir nuevas
instancias de otras clases.

Si ahora utilizamos un objeto de la clase Factura, solamente instanciando un objeto, los


valores iniciales se han creado desde el constructor.

public class UtilizacionFactura


{
public static void main(String[] args)
{
Factura f1 = new Factura();

System.out.println("Datos de la factura CONSTRUIDA");


System.out.println("Nombre Titular: " + f1.NombreTitular);
System.out.println("Concepto Factura: " +
f1.ConceptoFactura);
System.out.println("Precio: " + f1.Precio);
System.out.println("Iva: " + f1.Iva);
System.out.println("Total: " + f1.Total);
}
}

Campus Impúlsate | [email protected]


Como se puede observar la instanciación se realiza mediante la instrucción new seguido
del nombre de la clase y unos parámetros. En este caso el constructor no recibe ninguno.
Como resultado de la ejecución vemos los valores iniciales creados desde el constructor
(Figura 6):

Figura 6

1.7. Interacción entre los elementos


Los objetos intervienen en el comportamiento del sistema interaccionando con otros,
por ejemplo, en un coche un objeto pedal interacciona con el objeto freno, esto se
produce llamando a un método público que ofrece el objeto pedal para llevar a cabo
dicha acción, como resultado se produce una reducción de velocidad en el objeto coche.
A parte de definir objetos también estamos definiendo sus relaciones, un objeto delega
un trabajo a otro que puede ser parte suya u otro del sistema.

Como hemos visto en un objeto se pueden definir una serie de propiedades o métodos
de acceso público, ese conjunto lo denominamos parte publica o interfaz del objeto.
Otros objetos no necesitan saber cómo los demás llevan a cabo sus operaciones, solo
que la llamada a un método público produce un resultado. ( Ver diagrama de la Figura
7).

Figura 7 Representación de los métodos públicos de un objeto conectados a la implementación interna.

Campus Impúlsate | [email protected]


Para el desarrollo de una aplicación que interaccione con el usuario la estrategia básica
a seguir es conseguir una estructura en la que cada una de las partes realice una tarea
única e indivisible. Cada componente estaría coordinado por uno principal que obtiene
información a través de su interacción con el usuario. En la actualidad esta interacción
se realiza a través de un entorno gráfico y las órdenes se generan mediante eventos.

Para el desarrollo de un sistema es importante decidir de antemano como interaccionan


los objetos además de sus datos y responsabilidades. Es buena idea tener en cuenta
que para muchos casos ya se han realizado soluciones que se consideran óptimas o las
más apropiadas. Por ello nació el concepto de patrones de diseño software.
Simplificando, un patrón describe un problema genérico y su solución, un patrón no tiene
por qué ser una solución fija, pero ayuda a comprender como organizar un sistema para
que sus partes interaccionen de la mejor manera posible.

Como ejemplo tenemos en la siguiente imagen una representación el patrón de diseño


Modelo-Vista-Controlador o MVC, este patrón surge por la necesidad de separar los
datos y la lógica de negocio de interfaz del usuario. La clase que ocupa el rol de
controlador recibe notificaciones de la vista sobre su interacción con el usuario, como
por ejemplo pulsar un botón determinado o la introducción de texto. Cuando el
controlador es notificado sobre una acción realiza cambios sobre el modelo, este se
responsabiliza de guardar los datos y los cambios son enviados a la vista.

Figura 8 Diagrama del patrón de diseño Modelo-Vista-Controlador. Esta imagen representa la interacción entre los
principales componentes de una aplicación que interacciona con el usuario siguiendo el patrón de diseño MVC.

Por ejemplo, podemos tener una pantalla con los datos de una persona y botones de
Siguiente, Anterior y Guardar. La representación de los datos y la interacción con el
usuario son llevados a cabo por la vista. El usuario pulsa el botón siguiente y el

Campus Impúlsate | [email protected]


controlador es avisado, entonces hace que la siguiente bicicleta sea la seleccionada en
el modelo y por tanto la vista es notificada con la nueva información que será mostrada.

1.8. Ejemplo Interacción entre elementos.


Vamos a abrir un bloc de notas y escribiremos el código de nuestra primera clase.

Debemos recordar que Java es un lenguaje de programación "Case Sensitive", es decir,


diferencia entre mayúsculas y minúsculas, por lo que escribiremos literalmente el
contenido de nuestro primer ejemplo en el bloc de notas.

A continuación, vamos a guardar cada fichero con nuestro bloc de notas con el nombre
de la clase seguido por la extensión ".java" en la ubicación que vayamos a probar
nuestros ejemplos. Es recomendable crearnos una carpeta para poder ubicar todas
nuestras prácticas. Podemos utilizar cualquier otro editor de texto, pero es
imprescindible que sólo almacene texto plano, no nos valdrían editores de texto del
estilo Word o WordPad, ya que almacenan más información además del texto escrito,
un ejemplo de estos editores puede ser UltraEdit o algún bloc de notas "free" que se
encuentran en internet y que tienen más características que el bloc de notas tradiciones
de Windows.

Escritor.java:
public class Escritor{
//Parte privada
private String parteTexto1;
private String parteTexto2;
private int veces;
private String escribir(){
//Si no hay otra variable que se llame igual this no es
necesario
//La clase String tiene un metodo estatico para producir un
string a partir de otros tipos
String vecesString = String.valueOf(veces);
return parteTexto1 + veces + parteTexto2;
}

//Parte publica, interfaz al exterior


public Escritor(){
this.parteTexto1 = "En un lugar de la mancha de cuyo nombre
no quiero acordarme por ";
this.parteTexto2 = "ª vez";
this.veces = 0;
}
//En este caso le enviamos al lector un texto a traves de uno
de sus metodos
public void enviameTexto(Lector lector){
this.veces++;//Lo incrementamos
lector.enviar(this.escribir());
}
}

Campus Impúlsate | [email protected]


Lector.java:

public class Lector{


public int num;

public void pedirAlEscritor(Escritor escritor){


escritor.enviameTexto(this);//Le pasamos el objeto en si
}

public void enviar(String texto){


System.out.println("Soy el lector nº" + String.valueOf(num)
+ " y he recibido " + texto);
}
}

Main.java:

public class Main{


public static void main(String[] args){
Lector lector1 = new Lector();
Lector lector2 = new Lector();

lector1.num = 1;
lector2.num = 2;

Escritor cervantes = new Escritor();


lector1.pedirAlEscritor(cervantes);
lector2.pedirAlEscritor(cervantes);
lector1.pedirAlEscritor(cervantes);
}
}

Debemos asegurarnos que el nombre de nuestro fichero "java" debe tener el mismo
nombre que nuestra clase, incluida la diferenciación de mayúsculas y minúsculas, en
nuestro ejemplo tenemos Main.java, Escritor.java y Lector.java.

Voy a crear una carpeta en la unidad C:\Ejemplo2 y almacenaré las prácticas en dicha
ubicación. En el bloc de notas seleccionaremos como Tipo: "Todos los archivos" y
escribiremos la extensión ".java" para nuestra primera clase.

Hemos compilado los ficheros con el comando "javac *.java", y a continuación lo


ejecutamos con el comando "java -cp . Main", ten en cuenta el nombre de la clase
que contiene la función main como aparece en la imagen:

Campus Impúlsate | [email protected]


Figura 9 Mostramos el resultado de dos objetos interaccionando entre sí. Dos lectores solicita a un escritor que le
escriba algo y este responde.

Como podemos ver el objeto Escritor en su parte privada guarda el estado de cuantas
veces le han solicitado un texto y este responde en la respuesta mencionando que es
la 1ª, 2ª y 3ª vez. El objeto lector no conoce dicha parte privada y solo interesa la petición
de texto que ofrece en su parte pública. En este caso el objeto escritor también conoce
al lector, no usamos una función que devuelva el texto, sino que llama a una función del
objeto lector para responder.

Debido a la simplicidad de este ejemplo hemos usado un editor de texto simple, si se


desea también es posible utilizar un IDE (Integrated Development Environment), que
aporta funciones como la corrección de sintaxis y la compilación y ejecución desde una
interfaz gráfica. Ejemplos de IDEs libres o gratuitos son Eclipse o Netbeans.

Nota

Podremos guardar las prácticas en cualquier ubicación, pero es conveniente


guardarlas en alguna "ruta" fácilmente accesible ya que posteriormente tendremos
que escribir dicha ruta en nuestra ventana de comandos de Ms-Dos.

1.9. Interfaces II
Herencia

Antes de hablar de interfaces debemos hablar sobre el concepto de herencia en el


paradigma de orientación a objetos.

Imaginemos que tenemos las instrucciones para construir una silla concreta con unas
características y usos concretos, ahora supongamos que queremos crear una silla
basada en el diseño original, pero con algunos cambios, como por ejemplo unos
reposamuñecas. Como no cobramos por horas no vamos a escribir unas instrucciones
desde cero ya que tenemos los de la silla original, simplemente copiamos las partes en
común de las instrucciones originales y añadimos nuestra parte. Este es un ejemplo
sobre el concepto de herencia de objetos, tenemos definida una clase y queremos crear
una similar, pero con ciertos cambios.

Campus Impúlsate | [email protected]


Al heredar de una clase podemos usar los métodos y propiedades definidos
como protected o public por la clase padre. Desde fuera los objetos creados a partir de
la clase hija tendrán serán como el padre excepto por lo que hallamos añadido o
sobrescrito. (Ver diagrama de la Figura).

Figura 10 Un diagrama que muestra el concepto de herencia de manera simple. Tenemos una silla común, de la que
hereda una silla de escritorio y una con reposamuñecas y esta última a su vez tiene una de la que hereda con
reposamuñecas acolchado.

En este ejemplo consideramos que una "Silla de escritorio" es hija de "Silla común".

Además, de heredar de una clase normal tenemos el concepto de clase abstracta, esto
sería análogo al concepto abstracto que tenemos de una silla. Las clases abstractas no
pueden ser instanciadas, pero poseen una serie de propiedades y métodos comunes a
clases que la usan como padre. También es posible definir métodos abstractos, se
escriben como cualquier otro método, pero sin el bloque de código englobado en
corchetes. Toda clase que herede de otra con métodos abstractos debe
implementarlos.

Interfaces

Ahora que conocemos sobre la herencia podemos hablar del concepto de interfaces.

Un interface o interfaz en español es un conjunto de métodos abstractos y de


propiedades finales con la finalidad de definir el comportamiento de una clase.
Podemos considerar una interfaz como un "contrato" que debe seguir una clase.

La diferencia entre una interfaz y una clase abstracta es que la interfaz solo define que
se debe implementar y propiedades constantes mientras que una clase abstracta puede
implementar métodos o definirlos abstractos, la similitud que tienen es que ambas no
pueden instanciarse.

Campus Impúlsate | [email protected]


Una clase solamente puede derivar/heredar mediante extend de una clase base, pero
puede implementar varias interfaces. Los nombres de las interfaces se indican
separados por coma después de la palabra implements.

En Java una interfaz se define con la palabra interface seguido del nombre, también es
posible que una interfaz herede de otra o varias como lo haría una clase
mediante extends:

En este ejemplo creamos una interface con los métodos que queremos que se
implementen.

public interface InterfazCoche extends Vehiculo{


int V_MAXIMA = 120;

public void montar();


void comenzar();
void bajar();
int verVMaxima();
void cambiarVMaxima(int VMAXIMA);
void bajar();
void usar() throws IOException;
void menu();
}

Como se puede ver solo utilizamos el modificador public en una de las funciones, en
una interfaz todo método es implícitamente público, de manera que se puede omitir.
Además, todas las propiedades se consideran públicas, estáticas y constantes (public,
static y final), de la misma manera que las funciones, estas pueden ser omitidas.

Implementación de la interfaz

Si una clase quiere implementar una interfaz debe usar la palabra clave implements. Si
queremos heredar e implementar al mismo tiempo, debemos colocar primero extends
seguido del nombre de la clase y a continuación implements seguido del nombre de la
interfaz.

Sintaxis:

public class Macarrones extends Pasta implements Alimento,


Desechable,... {
//Cuerpo de la clase
}

public abstract class Fruta implements Alimento{


//..............
}

Campus Impúlsate | [email protected]


Si una clase implementa una interfaz podemos usar dicha interfaz como tipo en la
variable de los objetos. Por ejemplo, un objeto de Naranja que heredaría de Fruta (código
anterior), puede ser asignado a una variable con el tipo Alimento, dicha variable estaría
limitada por las funciones y constantes definidas en la interfaz Alimento. Por ejemplo,
podemos tener una clase CestaCompra que contenga una lista del tipo Alimento, de esta
manera podemos almacenar y usar objetos en base a una interfaz, aunque sean
originalmente instancias de distintas clases.

public class Naranja implements Alimento{


//..............
}

public class Galleta implements Alimento{


//..............
}

public class CestaCompra{


private ArrayList<Alimento> alimentos;
//......................

public void meter(Aliemento ali){


this.alimentos.add(ali);
}
}

Naranja naranja= new Naranja();


Alimento naranjaComoAlimento = naranja; //Desde esta variable se
considera alimento
Alimento galleta = new Galleta();
Galleta otraGalleta = new Galleta();
CestaCompra cesta = new CestaCompra();
cesta.meter(naranja);
cesta.meter(galleta);
cesta.meter(otraGalleta);

Campus Impúlsate | [email protected]


1.10. Peculiaridades de Java.
Como hemos visto Java sigue el paradigma de programación orientado a objetos, pero
eso no significa que pueda tener características de otros paradigmas como la
programación funcional. Por ejemplo, en la versión 8 se introdujeron conceptos de
programación funcional, dirigidos a ofrecer mejores soluciones a la hora de tratar con
grandes volúmenes de datos. Hay que tener en cuenta que las nuevas características en
el lenguaje son incompatibles con versiones anteriores de la JVM.

//Por ejemplo una función que suma uno a cada valor de una lista
de enteros
public List<Integer> addOne(List<Integer> numbers) { return
numbers .stream() .map(number -> number + 1)
.collect(Collectors.toList()); }

Por otra parte, antes de explicar el proceso de creación de un programa, conviene


explicar que en Java vamos a manejar tres tipos de aplicaciones:

• Aplicación en modo texto: En este tipo de aplicaciones la interacción con el


usuario (entrada de datos y presentación de resultados) se realiza en modo texto
(no existirán cajas de texto, botones, ...). El ratón no tendrá uso en estas
aplicaciones. Son las aplicaciones que realizaremos en el primer bloque donde
nuestro objetivo será aprender los conceptos básicos de Java. También es
interesante cuando realizamos los prototipos de nuestros programas debido a
que la depuración es más sencilla.
• Aplicación en modo gráfico: En este tipo de aplicaciones la interacción con el
usuario se realiza en modo gráfico. Estas aplicaciones pueden ser de todo tipo y
no hay que pensar sólo en Internet:
o Procesador de texto, bases de datos, entorno de programación,
tratamiento de gráficos...
• Miniaplicaciones (applets): Pequeños programas que no pueden ejecutarse de
forma independiente, sino que necesitan el soporte de un navegador. Estos
programas están pensados para que sean invocados desde una página HTML,
viajen a través de la red y se ejecuten en la máquina del cliente.

Campus Impúlsate | [email protected]

También podría gustarte