0% encontró este documento útil (0 votos)
264 vistas65 páginas

Prog Unidad 03

Cargado por

uombat
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
264 vistas65 páginas

Prog Unidad 03

Cargado por

uombat
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

25/12/2018 [Link]

id=3383

Utilización de objetos.

Caso práctico
Ada y Juan se han reunido para discutir sobre distintos proyectos de BK
Programación. Ada le comenta a Juan que están teniendo algunos problemas
con algunos de estos proyectos. A menudo surgen modificaciones o mejoras en
el software en el ámbito de los contratos de mantenimiento que tienen suscritos
con los clientes, y realizar las modificaciones en los programas está suponiendo
en muchos casos modificar el programa casi en su totalidad.

A eso se ha de sumar que las tareas de modificación son encargadas a las


Frank E. Weaver personas más adecuadas en ese momento, según la carga de trabajo que haya,
que no tienen por qué coincidir con las personas que desarrollaron el programa.
Las modificaciones en los proyectos se están retrasando, y hay algunas que deben estar listas antes de que surja el
nuevo cambio de versión.

En reuniones anteriores se ha comentado la posibilidad de aumentar el precio del contrato de mantenimiento de los
clientes. Se ha consultado con el equipo de comerciales y a regañadientes han aceptado un aumento que aún está por
decidir, pero aún así quizás no sea suficiente. La empresa necesita mejorar el método de trabajo para reducir
costes de mantenimiento del software y alcanzar la rentabilidad deseada.

[Link] 1/65
25/12/2018 [Link]

1.- Introducción.
Si nos paramos a observar el mundo que nos rodea, podemos apreciar que casi todo está formado
por objetos.

Existen coches, edificios, sillas, mesas, semáforos, ascensores e incluso personas o animales. Todos
ellos pueden ser considerados objetos, con una serie de características y comportamientos. Por
ejemplo, existen coches de diferentes marcas, colores, etc. y pueden acelerar, frenar, girar, etc., o las
personas tenemos diferente color de pelo, ojos, altura y peso y podemos nacer, crecer, comer, dormir,
etc.

Los programas son el resultado de la búsqueda y obtención de una solución para un problema
del mundo real. Pero ¿en qué medida los programas están organizados de la misma manera que el JoshuaDavisPhotography

problema que tratan de solucionar?

La respuesta es que muchas veces los programas se ajustan más a los términos del sistema en el que se ejecutarán que a los del
propio problema.

Si redactamos los programas utilizando los mismos términos de nuestro mundo real, es decir, utilizando objetos, y no los términos del
sistema o computadora donde se vaya a ejecutar, conseguiremos que éstos sean más legibles y, por tanto, más fáciles de
desarrollar, modificar y mantener, y por tanto, menos costosos.

Esto es precisamente lo que pretende la Programación Orientada a Objetos (POO), en inglés OOP (Object Oriented
Programming), establecer una serie de técnicas que permitan trasladar los problemas del mundo real a nuestro sistema informático.
Ahora que ya conocemos la sintaxis básica de Java, es el momento de comenzar a utilizar las características orientadas a objetos de
este lenguaje, y estudiar los conceptos fundamentales de este modelo de programación.

Autoevaluación
Rellena cada hueco con la palabra más adecuada.
La Programación Orientada a Objetos pretende establecer una serie de técnicas que permitan trasladar los
problemas del mundo real a nuestro sistema informático .
Reiniciar Mostrar las respuestas
Su puntuación es 5/5.

Seguro que te ha resultado fácil.

[Link] 2/65
25/12/2018 [Link]

2.- Fundamentos de la Programación Orientada a


Objetos.

Caso práctico
Juan cuenta con la ayuda de María para desarrollar la aplicación para la Clínica
Veterinaria. Lo normal es pensar en tener una aplicación de escritorio para las altas y
bajas de clientes y la gestión de mascotas, y una parte web para que la clínica pueda
estar presente en Internet, e incluso, realizar la venta on-line de sus productos. María
tiene bastante experiencia en administración de páginas web, pero para estar
capacitada en el desarrollo de aplicaciones en Java, necesita adquirir conocimientos
adicionales.

Juan le explica que tienen que utilizar un método de programación que les ayude a
organizar los programas, a trabajar en equipo de forma que si uno de ellos tiene que
Ryan O'Connell

dejar una parte para que se encargue el otro, que éste lo pueda retomar con el mínimo esfuerzo. Nadie del equipo
debe ser imprescindible para que el trabajo continúe. Además, interesa poder reutilizar todo el código que vayan
creando, para ir más rápido a la hora de programar. Juan le explica que si consiguen adoptar ese método de trabajo,
no sólo redundará en una mejor organización para ellos, sino que ayudará a que las modificaciones en los programas
sean más llevaderas de lo que lo están siendo ahora.

María asiente ante las explicaciones de Juan, e intuye que todo lo entenderá mejor conforme vaya conociendo los
conceptos de Programación Orientada a Objetos.

De lo que realmente se trata es de que BK Programación invierta el menor tiempo posible en los proyectos que
realice, aprovechando material elaborado con el esfuerzo ya realizado en otras aplicaciones.

Dentro de las distintas formas de hacer las cosas en programación, distinguimos dos paradigmas
fundamentales:

Programación Estructurada, se crean funciones o procedimientos que definen las


acciones a realizar, y que posteriormente forman los programas.
Programación Orientada a Objetos, considera los programas en términos de objetos y todo
gira alrededor de ellos.

Pero ¿en qué consisten realmente estos paradigmas?


bellydraft
Veamos estos dos modelos de programación con más detenimiento. Inicialmente se programaba
aplicando las técnicas de programación tradicional, también conocidas como Programación Estructurada. El problema se
descomponía en unidades más pequeñas hasta llegar a acciones o verbos muy simples y fáciles de codificar. Por ejemplo, en la
resolución de una ecuación de primer grado, lo que hacemos es descomponer el problema en acciones más pequeñas o pasos
diferenciados:

Pedir valor de los coeficientes.


Calcular el valor de la incógnita.
Mostrar el resultado.

Si nos damos cuenta, esta serie de acciones o pasos diferenciados no son otra cosa que verbos; por ejemplo el verbo pedir, calcular,
mostrar, etc.

Sin embargo, la Programación Orientada a Objetos aplica de otra forma diferente la técnica de programación divide y
vencerás. Este paradigma surge en un intento de salvar las dificultades que, de forma consustancial, posee el software. Para ello lo
que hace es descomponer, en lugar de acciones, en objetos. El principal objetivo sigue siendo descomponer el problema en
problemas más pequeños, que sean fáciles de manejar y mantener, fijándonos en cuál es el escenario del problema e intentando
reflejarlo en nuestro programa. O sea, se trata de trasladar la visión del mundo real a nuestros programas. Por este motivo se dice
que la Programación Orientada a Objetos aborda los problemas de una forma más natural, entendiendo como natural que está
más en contacto con el mundo que nos rodea, que es más cercana a nuestra forma de analizar, entender y resolver los problemas.

La Programación Estructurada se centra en el conjunto de acciones a realizar en un programa, haciendo una


división de procesos y datos. La Programación Orientada a Objetos se centra en la relación que existe entre los
datos y las acciones a realizar con ellos, y los encierra dentro del concepto de objeto, tratando de realizar una
abstracción lo más cercana al mundo real.

La Programación Orientada a Objetos es un sistema o conjunto de reglas que nos ayudan a descomponer la aplicación en
objetos. A menudo se trata de representar las entidades y objetos que nos encontramos en el mundo real mediante
componentes de una aplicación. Es decir, debemos establecer una correspondencia directa entre el espacio del problema y
el espacio de la solución.

[Link] 3/65
25/12/2018 [Link]
Pero, ¿qué quiere decir esto en la práctica?

Pues que a la hora de escribir un programa, nos fijaremos en los objetos involucrados, sus características comunes y las acciones
que pueden realizar. Una vez localizados los objetos que intervienen en el problema real (espacio del problema), los tendremos que
trasladar al programa informático (espacio de la solución). Con este planteamiento, la solución a un problema dado se convierte en
una tarea sencilla y bien organizada.

Autoevaluación
Relaciona el término con su definición, escribiendo el número asociado a la definición en el hueco
correspondiente.

Ejercicio de relacionar
Paradigma Relación Definición

Programación Orientada a 1. Maneja funciones y procedimientos que definen las acciones a


2
Objetos. realizar.

2. Representa las entidades del mundo real mediante componentes de


Programación Estructurada. 1
la aplicación.

Reiniciar Mostrar las respuestas


Su puntuación es 2/2.

La Programación Orientada a Objetos y la Programación Estructurada son paradigmas o modelos de


programación.

[Link] 4/65
25/12/2018 [Link]

2.1.- Conceptos.
Para entender mejor la filosofía de orientación a objetos veamos algunas características que la diferencian de las técnicas de
programación tradicional.

En la Programación Estructurada, el programa estaba compuesto por un conjunto de datos y funciones "globales". El término
global significaba que eran accesibles por todo el programa, pudiendo ser llamados en cualquier ubicación de la aplicación. Dentro
de las funciones se situaban las instrucciones del programa que manipulaban los datos. Funciones y datos se encontraban
separados y totalmente independientes. Esto ocasionaba dos problemas principales:

Los programas se creaban y estructuraban de acuerdo con la arquitectura de la computadora donde se tenían que ejecutar.
Al estar separados los datos de las funciones, éstos eran visibles en toda la aplicación. Ello ocasionaba que cualquier
modificación en los datos podía requerir la modificación en todas las funciones del programa, en correspondencia con los
cambios en los datos.

En la Programación Orientada a Objetos la situación es diferente. La utilización de objetos permite un mayor nivel de
abstracción que con la Programación Estructurada, y ofrece las siguientes diferencias con respecto a ésta:

El programador organiza su programa en objetos, que son representaciones del mundo real que están más cercanas a la
forma de pensar de la gente.
Los datos, junto con las funciones que los manipulan, son parte interna de los objetos y no están accesibles al resto de los
objetos. Por tanto, los cambios en los datos de un objeto sólo afectan a las funciones definidas para ese objeto, pero no al resto
de la aplicación.

Todos los programas escritos bajo el paradigma orientado a Objetos se pueden escribir igualmente mediante la Programación
Estructurada. Sin embargo, la Programación Orientada a Objetos es la que mayor facilidad presenta para el desarrollo de programas
basados en interfaces gráficas de usuario.

Autoevaluación
Marca las afirmaciones que sean correctas, referidas a la Programación Orientada a Objetos.

Los datos, junto con las funciones que los manipulan, son parte interna de los objetos y no están accesibles al
resto de los objetos.

Los programas se crean y estructuran de acuerdo con la arquitectura de la computadora donde se van a ejecutar.

Los cambios en los datos de un objeto afectan a las funciones definidas para ese objeto así como al resto de la
aplicación.

Al programar organizamos el código en torno a objetos, que son representaciones del mundo real que están más
cercanas a la forma de pensar de la gente.

Mostrar retroalimentación

[Link] 5/65
25/12/2018 [Link]

Solución

1. Correcto
2. Incorrecto
3. Incorrecto
4. Correcto

[Link] 6/65
25/12/2018 [Link]

2.2.- Beneficios.
Según lo que hemos visto hasta ahora, un objeto es cualquier entidad que podemos ver o
apreciar.

El concepto fundamental de la Programación Orientada a Objetos son, precisamente, los


objetos. Pero ¿qué beneficios aporta la utilización de objetos?

Fundamentalmente la posibilidad de representar el problema en términos del mundo real, que


como hemos dicho están más cercanos a nuestra forma de pensar, pero existen otra serie de
ventajas como las siguientes:

Comprensión. Los conceptos del espacio del problema se hayan reflejados en el código del programa, por lo que la mera
lectura del código nos describe la solución del problema en el mundo real.
Modularidad. Facilita la modularidad del código, al estar las definiciones de objetos en módulos o archivos independientes,
hace que las aplicaciones estén mejor organizadas y sean más fáciles de entender.
Fácil mantenimiento. Cualquier modificación en las acciones queda automáticamente reflejada en los datos, ya que ambos
están estrechamente relacionados. Esto hace que el mantenimiento de las aplicaciones, así como su corrección y modificación
sea mucho más fácil. Por ejemplo, podemos querer utilizar un algoritmo más rápido, sin tener que cambiar el programa
principal. Por otra parte, al estar las aplicaciones mejor organizadas, es más fácil localizar cualquier elemento que se quiera
modificar y/o corregir. Esto es importante ya que se estima que los mayores costes de software no están en el proceso de
desarrollo en sí, sino en el mantenimiento posterior de ese software a lo largo de su vida útil.
Seguridad. La probabilidad de cometer errores se ve reducida, ya que no podemos modificar los datos de un objeto
directamente, sino que debemos hacerlo mediante las acciones definidas para ese objeto. Imaginemos un objeto lavadora. Se
compone de un motor, tambor, cables, tubos, etc. Para usar una lavadora no se nos ocurre abrirla y empezar a manipular esos
elementos, ya que lo más probable es que se estropee. En lugar de eso utilizamos los programas de lavado establecidos. Pues
algo parecido con los objetos, no podemos manipularlos internamente, sólo utilizar las acciones que para ellos hay definidas.
Reusabilidad. Los objetos se definen como entidades reutilizables, es decir, que los programas que trabajan con las mismas
estructuras de información, pueden reutilizar las definiciones de objetos empleadas en otros programas, e incluso las acciones
definidas sobre ellos. Por ejemplo, podemos crear la definición de un objeto de tipo Persona para una aplicación de negocios y
deseamos construir a continuación otra aplicación, digamos de educación, en donde utilizamos también personas, no es
necesario crear de nuevo el objeto, sino que por medio de la reusabilidad podemos utilizar el tipo de objeto Persona
previamente definido.

Citas para pensar

Primero resuelve el problema. Entonces, escribe el código.

John Johnson.

Autoevaluación
Marca la opción que NO se corresponda con uno de los beneficios de la Programación Orientada a Objetos.

Modularidad.

Reusabilidad.

Complejidad en el mantenimiento.

Comprensión.

No has acertado, la modularidad del código sí es un beneficio de la POO, al estar las definiciones de objetos en
módulos o archivos independientes, hace que las aplicaciones estén mejor organizadas y sean más fáciles de
entender.

Incorrecto. La POO sí facilita la reusabilidad. Los programas que trabajan con las mismas estructuras de
información, pueden reutilizar las definiciones de objetos empleadas en otros programas, e incluso las acciones
definidas sobre ellos.

¡Correcto! Efectivamente, la complejidad en el mantenimiento difícilmente podría ser un beneficio, pero es que
además, la POO facilita el mantenimiento al estar las aplicaciones mejor organizadas, es más fácil localizar
[Link] 7/65
25/12/2018 [Link]
cualquier elemento que se quiera modificar y/o corregir.

No es correcto. Con la POO, los conceptos del espacio del problema se hayan reflejados en el código del
programa, por lo que la mera lectura del código nos describe la solución del problema en el mundo real.

Solución

1. Incorrecto
2. Incorrecto
3. Opción correcta
4. Incorrecto

[Link] 8/65
25/12/2018 [Link]

2.3.- Características.
Cuando hablamos de Programación Orientada a Objetos, existen una serie de características que
se deben cumplir. Cualquier lenguaje de programación orientado a objetos las debe contemplar. Las
características más importantes del paradigma de la programación orientada a objetos son:

Abstracción. Es el proceso por el cual definimos las características más importantes de un


objeto, sin preocuparnos de cómo se escribirán en el código del programa, simplemente lo
definimos de forma general. En la Programación Orientada a Objetos la herramienta más
importante para soportar la abstracción es la clase. Básicamente, una clase es un tipo de
dato que agrupa las características comunes de un conjunto de objetos. Poder ver los objetos
del mundo real que deseamos trasladar a nuestros programas, en términos abstractos, resulta Helena

de gran utilidad para un buen diseño del software, ya que nos ayuda a comprender mejor el problema y a tener una visión
global de todo el conjunto. Por ejemplo, si pensamos en una clase Vehículo que agrupa las características comunes de todos
ellos, a partir de dicha clase podríamos crear objetos como Coche y Camión. Entonces se dice que Vehículo es una
abstracción de Coche y de Camión.
Modularidad. Una vez que hemos representado el escenario del problema en nuestra aplicación, tenemos como resultado un
conjunto de objetos software a utilizar. Este conjunto de objetos se crean a partir de una o varias clases. Cada clase se
encuentra en un archivo diferente, por lo que la modularidad nos permite modificar las características de la clase que define un
objeto, sin que esto afecte al resto de clases de la aplicación.
Encapsulación. También llamada "ocultamiento de la información". La encapsulación o encapsulamiento es el
mecanismo básico para ocultar la información de las partes internas de un objeto a los demás objetos de la aplicación. Con la
encapsulación un objeto puede ocultar la información que contiene al mundo exterior, o bien restringir el acceso a la misma
para evitar ser manipulado de forma inadecuada. Por ejemplo, pensemos en un programa con dos objetos, un objeto Persona
y otro Coche. <code>Persona se comunica con el objeto Coche para llegar a su destino, utilizando para ello las acciones que
Coche tenga definidas, como por ejemplo, conducir. Es decir, Persona utiliza Coche, pero no sabe cómo funciona
internamente, sólo sabe utilizar sus métodos o acciones.
Jerarquía. Mediante esta propiedad podemos definir relaciones de jerarquías entre clases y
objetos. Las dos jerarquías más importantes son la jerarquía "es un" llamada
generalización o especialización y la jerarquía "es parte de", llamada agregación.
Conviene detallar algunos aspectos:
La generalización o especialización, también conocida como herencia, permite crear
una clase nueva en términos de una clase ya existente (herencia simple) o de varias
clases ya existentes (herencia múltiple). Por ejemplo, podemos crear la clase
CocheDeCarreras a partir de la clase Coche, y así sólo tendremos que definir las nuevas características que tenga.
La agregación, también conocida como inclusión, permite agrupar objetos relacionados entre sí dentro de una clase. Así,
un Coche está formado por Motor, Ruedas, Frenos y Ventanas. Se dice que Coche es una agregación y Motor,
Ruedas, Frenos y Ventanas son agregados de Coche.
Polimorfismo. Esta propiedad indica la capacidad de que varias clases creadas a partir de una antecesora realicen una misma
acción de forma diferente. Por ejemplo, pensemos en la clase Animal y la acción de expresarse. Nos encontramos que cada
tipo de Animal puede hacerlo de manera distinta, los Perros ladran, los Gatos maúllan, las Personas hablamos, etc. Dicho de
otra manera, el polimorfismo indica la posibilidad de tomar un objeto (de tipo Animal, por ejemplo), e indicarle que realice la
acción de expresarse, esta acción será diferente según el tipo de mamífero del que se trate.

Autoevaluación
Completa la frase, rellenando los huecos con la palabra adecuada.
La propiedad que indica la capacidad de que varias clases creadas a partir de una antecesora realicen una misma
acción de forma diferente recibe el nombre de . Eso quiere decir que cuando pedimos a un
que realice una misma acción, la respuesta va a ser dependiendo del objeto que realice
esa acción.
Enviar

Más adelante veremos que las acciones que se envían a los objetos se llaman métodos o mensajes, y que un
mismo método puede reescribirse de formas distintas para distintos tipos de objetos, de forma que el mismo
mensaje enviado a varios objetos de distintos tipos, hará que cada uno lo realice usando su propio código, por
lo que la respuesta puede ser diferente.

[Link] 9/65
25/12/2018 [Link]

2.4.- Lenguajes de programación orientados a


objetos.
Una panorámica de la evolución de los lenguajes de programación orientados a objetos hasta llegar a
los utilizados actualmente es la siguiente:

Simula (1962). El primer lenguaje con objetos fue B1000 en 1961, seguido por Sketchpad en
1962, el cual contenía clones o copias de objetos. Sin embargo, fue Simula el primer lenguaje
que introdujo el concepto de clase, como elemento que incorpora datos y las operaciones sobre
esos datos. En 1967 surgió Simula 67 que incorporaba un mayor número de tipos de datos,
además del apoyo a objetos.
SmallTalk (1972). Basado en Simula 67, la primera versión fue Smalltalk 72, a la que siguió Quasar
Smalltalk 76, versión totalmente orientada a objetos. Se caracteriza por soportar las principales
propiedades de la Programación Orientada a Objetos y por poseer un entorno que facilita el rápido desarrollo de aplicaciones.
El Modelo-Vista-Controlador ( MVC) fue una importante contribución de este lenguaje al mundo de la programación. El
lenguaje Smalltalk ha influido sobre otros muchos lenguajes como C++ y Java.
C++ (1985). C++ fue diseñado por Bjarne Stoustrup en los laboratorios donde trabajaba, entre 1982 y 1985. Lenguaje que
deriva del C, al que añade una serie de mecanismos que le convierten en un lenguaje orientado a objetos. No tiene recolector
de basura automática, lo que obliga a utilizar un destructor de objetos no utilizados. En este lenguaje es donde aparece el
concepto de clase tal y como lo conocemos actualmente, como un conjunto de datos y funciones que los manipulan.
Eiffel (1986). Creado en 1985 por Bertrand Meyer, recibe su nombre en honor a la famosa torre de París. Tiene una sintaxis
similar a C. Soporta todas las propiedades fundamentales de los objetos, utilizado sobre todo en ambientes universitarios y de
investigación. Entre sus características destaca la posibilidad de traducción de código Eiffel a Lenguaje C. Aunque es un
lenguaje bastante potente, no logró la aceptación de C++ y Java.
Java (1995). Diseñado por James Gosling de Sun Microsystems a finales de 1995. Es un lenguaje orientado a objetos diseñado
desde cero, que recibe muchas influencias de C++. Como sabemos, se caracteriza porque produce un bytecode que
posteriormente es interpretado por la máquina virtual. La revolución de Internet ha influido mucho en el auge de Java.
C# (2000). El lenguaje C#, también es conocido como C Sharp. Fue creado por Microsoft, como una ampliación de C con
orientación a objetos. Está basado en C++ y en Java. Una de sus principales ventajas que evita muchos de los problemas de
diseño de C++.

Autoevaluación
Relaciona los lenguajes de programación indicados con la característica correspondiente, escribiendo el
número asociado a la característica en el hueco correspondiente.

Ejercicio de relacionar

Lenguaje de
Relación Tiene la característica de que …
programación

Java 1.- Fue el primer lenguaje que introdujo el concepto de clase.

SmallTalk 2.- Introdujo el concepto del Modelo-Vista-Controlador.

Simula 3.- Produce un bytecode para ser interpretado por la máquina virtual.

4.- Introduce el concepto de clase tal cual lo conocemos, con atributos y


C++
métodos.

Enviar

C++ fue diseñado basándose en C y añadiéndole la orientación a objetos. Posteriormente, surgiría Java, que
recibió influencias de C++ y de Ada-95.

[Link] 10/65
25/12/2018 [Link]

3.- Clases y Objetos. Características de los objetos.

Caso práctico
María ha hecho un descanso de cinco minutos.

Se está tomando un café y está repasando los conceptos de Programación Orientada a


Objetos. Piensa que este paradigma supone un cambio de enfoque con respecto a las
técnicas tradicionales. Ahora lo que necesita es ahondar en el concepto de objeto, que
parece ser el eje central de este modelo de programación.

rport

Al principio de la unidad veíamos que el mundo real está compuesto de objetos, y podemos considerar objetos casi cualquier cosa
que podemos ver y sentir. Cuando escribimos un programa en un lenguaje orientado a objetos, debemos identificar cada una de las
partes del problema con objetos presentes en el mundo real, para luego trasladarlos al modelo computacional que estamos creando.

En este contexto, un objeto de software es una representación de un objeto del mundo real, compuesto de una serie de
características y un comportamiento específico. Pero ¿qué es más concretamente un objeto en Programación Orientada a Objetos?
Veámoslo.

Un objeto es un conjunto de datos con las operaciones definidas para ellos. Los objetos tienen un estado y un
comportamiento.

Por tanto, estudiando los objetos que están presentes en un problema podemos dar con la
solución a dicho problema. Los objetos tienen unas características fundamentales que los
distinguen:

Identidad. Es la característica que permite diferenciar un objeto de otro. De esta manera,


aunque dos objetos sean exactamente iguales en sus atributos, son distintos entre sí. Puede
ser una dirección de memoria, el nombre del objeto o cualquier otro elemento que utilice el
lenguaje para distinguirlos. Por ejemplo, dos vehículos que hayan salido de la misma
cadena de fabricación y sean iguales aparentemente, son distintos porque tienen un código que los identifica.
Estado. El estado de un objeto viene determinado por una serie de parámetros o atributos que lo describen, y los valores de
éstos. Por ejemplo, si tenemos un objeto Coche, el estado estaría definido por atributos como Marca, Modelo, Color, Cilindrada,
etc.
Comportamiento. Son las acciones que se pueden realizar sobre el objeto. En otras palabras, son los métodos o
procedimientos que realiza el objeto. Siguiendo con el ejemplo del objeto Coche, el el comportamiento serían acciones como:
arrancar(), parar(), acelerar(), frenar(), etc.

[Link] 11/65
25/12/2018 [Link]

3.1.- Propiedades y métodos de los objetos.


Como acabamos de ver todo objeto tiene un estado y un comportamiento.

Concretando un poco más, las partes de un objeto son:

Campos, Atributos o Propiedades. Son la parte del objeto que almacena los datos.
También se les denomina variables miembro. Estos datos pueden ser de cualquier tipo
primitivo (boolean, char, int, double, etc.) o ser a su vez otro objeto. Por ejemplo, un objeto
de la clase Coche puede tener varios objetos de la clase Rueda.
Métodos o Funciones Miembro. Son la parte del objeto que lleva a cabo las operaciones
sobre los atributos definidos para ese objeto.

La idea principal es que el objeto reúne en una sola entidad los datos y las operaciones, y para acceder a los datos privados del
objeto debemos utilizar los métodos que hay definidos para ese objeto.

La única forma de manipular la información del objeto es a través de sus métodos. Es decir, si queremos saber el valor de
algún atributo, tenemos que utilizar el método que nos muestre el valor de ese atributo. De esta forma, evitamos que métodos
externos puedan alterar los datos del objeto de manera inadecuada. Se dice que los datos y los métodos están encapsulados
dentro del objeto.

Autoevaluación
Completa el texto escribiendo la palabra adecuada en cada hueco.
El estado de un objeto viene definido por sus , mientras que su comportamiento viene definido por
sus .
Enviar

Son los métodos los que definen las acciones que un objeto puede realizar, y por tanto su comportamiento,
mientras que los atributos, con los valores que toman en un momento concreto, conforman el estado del objeto
en ese momento.

[Link] 12/65
25/12/2018 [Link]

3.2.- Interacción entre objetos.


¿Pero los distintos objetos de un programa pueden tener algún tipo de comunicación entre ellos?

Dentro de un programa los objetos se comunican llamando unos a los métodos de otros. Los métodos están dentro de los objetos
y describen el comportamiento de un objeto cuando recibe una llamada a uno de sus métodos. En otras palabras, cuando un objeto,
objeto1, quiere actuar sobre otro, objeto2, tiene que ejecutar uno de sus métodos. Entonces se dice que el objeto2 recibe un
mensaje del objeto1.

Un mensaje es la solicitud a un objeto para que realice una determinada acción.


Un método es la función o procedimiento al que se llama para actuar sobre un objeto.

Los distintos mensajes que puede recibir un objeto o a los que puede responder reciben el nombre de
protocolo de ese objeto.

El proceso de interacción entre objetos se suele resumir diciendo que se ha "enviado un


mensaje" (hecho una petición) a un objeto, y el objeto determina "qué hacer con el mensaje"
(ejecuta el código del método).

Cuando se ejecuta un programa se producen las siguientes acciones:


Srinath66

Creación de los objetos a medida que se necesitan.


Comunicación entre los objetos mediante el envío de mensajes de unos a otros, o el usuario a los objetos.
Eliminación de los objetos cuando no son necesarios para dejar espacio libre en la memoria del ordenador.

Los objetos se pueden comunicar entre ellos invocando a los métodos de los otros objetos.

Autoevaluación

Cuando un objeto, objeto1, ejecuta un método de otro, objeto2, se dice que el objeto2 le ha mandado un
mensaje al objeto1.

Verdadero Falso

Falso
En este caso se dice que es el objeto1 el que le ha mandado un mensaje al objeto2.

[Link] 13/65
25/12/2018 [Link]

3.3.- Clases.
Hasta ahora hemos visto lo que son los objetos.

Piensa en el mundo real, en un tipo de objeto, una galleta y en el proceso industrial de


producción de galletas. No necesitamos hacer y hornear una sola galleta, sino que lo normal
será hacer y hornear un montón de ellas. Para realizar ese proceso, seguro que nos resulta útil
disponer de un molde que establezca cómo va a ser cada objeto galleta. Pues bien, algo así
ocurre en programación con los objetos, que usamos "moldes" para construirlos.

Un programa informático se compone de muchos objetos, algunos de los cuales comparten la misma estructura y comportamiento. Si
tuviéramos que definir la estructura y comportamiento del objeto cada vez que queremos crear un objeto, estaríamos utilizando
mucho código redundante. Por ello lo que se hace es crear una clase, que es una descripción de un conjunto de objetos que
comparten una estructura y un comportamiento común. Y a partir de la clase, se crean tantas "copias" o "instancias" como
necesitemos. Esas copias son los objetos de la clase.

Las clases constan de datos y métodos que resumen las características comunes de un conjunto de objetos.
Un programa informático está compuesto por un conjunto de clases, a partir de las cuales se crean objetos que
interactúan entre sí.

Si recuerdas, cuando utilizábamos los tipos de datos enumerados, los definíamos con la palabra reservada enum y la lista de valores
entre llaves, y decíamos que un tipo de datos enum no es otra cosa que una especie de clase en Java. Efectivamente, todas las
clases llevan su contenido entre llaves. Y una clase tiene la misma estructura que un tipo de dato enumerado, añadiéndole una serie
de métodos y variables.

En otras palabras, una clase es una plantilla o prototipo donde se especifican:

Los atributos comunes a todos los objetos de la clase.


Los métodos que pueden utilizarse para manejar esos objetos.

Para declarar una clase en Java se utiliza la palabra reservada class. La declaración de una clase está compuesta por:

Cabecera de la clase. La cabecera es un poco más compleja que como aquí definimos, pero por ahora sólo nos interesa saber
que está compuesta por una serie de modificadores. En este caso hemos puesto public, que indica que es una clase pública a
la que pueden acceder otras clases del programa, la palabra reservada class y el nombre de la clase.
Cuerpo de la clase. En él se especifican encerrados entre llaves los atributos y los métodos que va a tener la clase.

Estructura de una clase en Java (1 KB)

En las unidades anteriores ya hemos utilizado clases, aunque aún no sabíamos apenas nada sobre su significado exacto.

Por ejemplo, en los ejemplos de la unidad o en la tarea, estábamos utilizando clases, todas ellas eran clases principales, no tenían
ningún atributo y el único método del que disponían era el método main().

El método main() se utiliza para indicar que se trata de una clase principal, a partir de la cual va a empezar la
ejecución del programa.

Este método no aparece si la clase que estamos creando no va a ser la clase principal del programa.

[Link] 14/65
25/12/2018 [Link]

4.- Utilización de objetos.

Caso práctico
María sigue fuera de la oficina. Esta noche en casa quiere repasar conceptos sobre
Programación Orientada a Objetos, así que aprovecha un momento para llamar a Juan
y le comenta:

—Ya sé todo sobre objetos -le dice- sólo que...

—Solo que.... ¿qué? -añade Juan.

—Solo me falta saber una cosa, ¿cómo se crea un objeto?


Jose Maria Cuellar

Juan sonríe ante la pregunta de María, y le explica que los objetos se crean como si fuera declarando una variable
más, tan sólo que el tipo de datos de dicho objeto será una clase. Tras declararlos hay que instanciarlos con el
operador new para reservar memoria para ellos, y después ya podremos utilizarlos, refiriéndonos a su contenido con el
operador punto.

—Te mando un documento por correo electrónico que lo explica todo muy bien.

—¡Ah, gracias! Esta noche le echo un vistazo.

Una vez que hemos creado una clase, podemos crear objetos en nuestro programa a partir de esas clases.

Cuando creamos un objeto a partir de una clase se dice que hemos creado una "instancia de la clase". A efectos prácticos, "objeto"
e "instancia de clase" son términos similares. Es decir, nos referimos a objetos como instancias cuando queremos hacer hincapié que
son de una clase particular.

Los objetos se crean a partir de las clases, y representan "casos individuales" de éstas.

Para entender mejor el concepto entre un objeto y su clase, piensa de nuevo en un molde de galletas
y en las propias galletas.

El molde sería la clase, que define las características del objeto, por ejemplo su forma y tamaño. Las
galletas creadas a partir de ese molde son los objetos o instancias, y todos los objetos de esa clase,
aun siendo distintos, se parecerán bastante, ya que tendrán las mismas características generales.

Otro ejemplo, imagina una clase Persona que reúna las características comunes de las personas
(nombre, NIF, color de pelo, color de ojos, peso, altura, etc.) y las acciones que pueden realizar
medea_material
(crecer, dormir, comer, etc.). Posteriormente dentro del programa podremos crear un objeto trabajador
que esté basado en esa clase Persona. Entonces se dice que el objeto trabajador es una instancia de la clase Persona, o que la
clase Persona es una abstracción del objeto trabajador.

Cualquier objeto instanciado de una clase contiene una copia de todos los atributos definidos en la clase. En otras palabras, lo que
está haciendo el operador new al instanciarlo es reservar el espacio necesario en la memoria del ordenador para guardar sus
atributos y métodos, siguiendo para ello las indicaciones que le da la propia clase. Por tanto, cada objeto tiene una zona de
almacenamiento propia donde se guarda toda su información, que será distinta a la de cualquier otro objeto. A las variables
miembro instanciadas también se les llama variables instancia, o simplemente instancias. De igual forma, a los métodos que
manipulan esas variables se les llama métodos de instancia.

En el ejemplo del objeto trabajador, las variables instancia serían colorDePelo, peso, altura, etc. Y los métodos de instancia serían
crecer(), dormir(), comer(), etc.

Autoevaluación

Un objeto es como un molde para crear clases.

Verdadero Falso

Falso
Una clase es una estructura parecida a un molde para crear objetos a partir de ella.

[Link] 15/65
25/12/2018 [Link]

[Link] 16/65
25/12/2018 [Link]

4.1.- Ciclo de vida de los objetos.


Todo programa en Java parte de una única clase, que como hemos comentado se trata de la
clase principal. Esta clase ejecutará el contenido de su método main(), el cual será el que utilice
las demás clases del programa, cree objetos y lance mensajes a otros objetos.

Las instancias u objetos tienen un tiempo de vida determinado. Cuando un objeto no se va a


utilizar más en el programa, es destruido por el recolector de basura para liberar recursos que
pueden ser reutilizados por otros objetos.

A la vista de lo anterior, podemos concluir que los objetos tienen un ciclo de vida, en el cual podemos distinguir las siguientes fases:

Creación, donde se hace la reserva de memoria e inicialización de atributos.


Manipulación, que se lleva a cabo cuando se hace uso de los atributos y métodos del objeto.
Destrucción, eliminación del objeto y liberación de recursos.

[Link] 17/65
25/12/2018 [Link]

4.2.- Declaración.
Para la creación de un objeto hay que seguir los siguientes pasos:

Declaración: definir el tipo de objeto.


Instanciación: creación del objeto utilizando el operador new.

Pero ¿en qué consisten estos pasos, en el contexto de la programación en Java?

Veamos primero cómo declarar un objeto. Para la definición del tipo de objeto debemos emplear la Ramesh NG
siguiente instrucción:

<tipo> nombreObjeto;

Donde:

tipo es la clase a partir de la cual se va a crear el objeto, y


nombreObjeto es el nombre de la variable referencia con la cual nos referiremos al objeto.

Los tipos referenciados o referencias se utilizan para guardar la dirección de los datos en la memoria del
ordenador.

Nada más crear una referencia, ésta se encuentra vacía. Cuando una referencia a un objeto no contiene ninguna instancia se dice
que es una referencia nula, es decir, que contiene el valor null. (También se dice que apunta a null). Esto quiere decir que la
referencia está creada, pero que el objeto no está instanciado todavía, es decir, hemos preparado la referencia indicando a qué tipo
de objetos va a apuntar, pero todavía no hemos reservado memoria para el objeto, así que no está apuntando a ninguna posición de
memoria que contenga ese objeto, y para que no haya confusión posible, la referencia apunta a un objeto inexistente llamado null
(nulo).

Para entender mejor la declaración de objetos veamos un ejemplo.

Cuando veíamos los tipos de datos primitivos, decíamos que Java proporciona un tipo de dato especial para los textos o cadenas de
caracteres que era el tipo de dato String. Veíamos que realmente este tipo de dato es un tipo referenciado y creábamos una
variable mensaje de ese tipo de dato de la siguiente forma:

String mensaje;

Los nombres de la clase empiezan con mayúscula, como String, y los nombres de los objetos con minúscula,
como mensaje, así sabemos qué tipo de elemento se está utilizando.

Pues bien, String es realmente una clase que nos proporciona Java para facilitar el trabajo con cadenas de texto, a partir de la cual
creamos nuestro objeto llamado mensaje.

Si observas, poco se diferencia esta declaración de las declaraciones de variables que hacíamos para los tipos primitivos. Antes
decíamos que mensaje era una variable del tipo de dato String. Ahora realmente vemos que mensaje es una referencia a un objeto
de la clase String. Pero mensaje aún no contiene el objeto porque no ha sido instanciado, veamos cómo hacerlo.

Por tanto, cuando creamos un objeto estamos haciendo uso de una variable que almacena la dirección de ese objeto en memoria.
Esa variable es una referencia o un tipo de dato referenciado, porque no contiene el dato, si no la posición del dato en la memoria
del ordenador.

String saludo = new String ("Bienvenido a Java");


String s; //s vale null
s = saludo; //asignación de referencias

En las instrucciones anteriores, las variables s y saludo acaban apuntando al mismo objeto de la clase String. Esto implica que
cualquier modificación en el objeto saludo modifica también el objeto al que hace referencia la variable s, ya que realmente son el
mismo. Es decir, cualquier modificación que haga usando saludo, se hará sobre el objeto, y puesto que s apunta al mismo objeto,
será visible también a través de s.

Autoevaluación
Indica si las siguientes afirmaciones son verdaderas o falsas.

[Link] 18/65
25/12/2018 [Link]

Las referencias se utilizan para almacenar los datos del objeto.

Verdadero Falso

Falso
Es falso, puesto que las referencias lo que almacenan es la dirección de memoria en la que realmente están los
datos del objeto. Por eso decimos que "apuntan" al objeto.

A la hora de nombrar clases siguiendo el convenio generalmente aceptado, siempre comenzaremos con
mayúsculas, cada primera letra de cada palabra que forme el nombre de la clase, incluida la primera palabra,
con el resto de letras en minúscula, sin usar espacios en blanco, ni caracteres acentuados, ni signos de $, ni
carácter de subrayado.

Verdadero Falso

Verdadero
Por eso, camionDeCarreras, Camion_De_Carreras, CAMIONDECARRERAS, CamiónDeCarreras, serían ejemplos de
identificadores poco deseables, que no cumplen el convenio, mientras que el nombre apropiado para esta clase
sería CamionDeCarreras.

[Link] 19/65
25/12/2018 [Link]

4.3.- Instanciación.
Una vez creada la referencia al objeto, debemos crear la instancia u objeto a la que va a apuntar esa referencia. Para ello utilizamos
el operador new con la siguiente sintaxis:

nombreObjeto = new <ConstructorDeLaClase>([<parametro1>, <par<code>ametro2>, ..., N>]);

Donde:

nombreObjeto es el nombre de la variable referencia con la cual nos referiremos al objeto.


new es el operador para crear el objeto.
ConstructorDeLaClase es un método especial de la clase, que se llama igual que ella, y se
encarga de inicializar el objeto, es decir, de dar unos valores iniciales a sus atributos.
par<code>ametro1,...,parametroN, son parámetros que puede o no necesitar el constructor para
dar los valores iniciales a los atributos del objeto.

Durante la instanciación del objeto, se reserva memoria suficiente para el objeto. De esta tarea se manuelfloresv

encarga Java y desempeña un papel muy importante el recolector de basura, que se encarga de
eliminar de la memoria los objetos que ya han quedado descolgados (sin ninguna referencia que los apunte) y por tanto ya no van a
poder volver a ser utilizados, para que la memoria que ocupaban pueda volver a estar disponible para ser usada.

De este modo, para instanciar un objeto String, haríamos lo siguiente:

mensaje = new String();

Así estaríamos instanciando el objeto mensaje. Para ello utilizaríamos el operador new y el constructor de la clase String a la que
pertenece el objeto según la declaración que hemos hecho en el apartado anterior. A continuación utilizamos el constructor, que se
llama igual que la clase, String.

En el ejemplo anterior el objeto se crearía con la cadena vacía (""), si queremos que tenga un contenido debemos utilizar parámetros
en el constructor, así:

mensaje = new String ("El primer programa");

Aunque String es una clase, se trata de una clase muy especial.

Java permite utilizar la clase String como si de un tipo de dato primitivo se tratara, por eso no hace falta utilizar el
operador new para instanciar un objeto de la clase String, aunque también permite hacerlo como para cualquier
otra clase. Por tanto las sentencias mensaje=new String("El primer programa"); y mensaje="El primer programa";
son totalmente equivalentes.

Llamamos también tu atención sobre el hecho de que no es lo mismo decir que una referencia de tipo String
apunte a la cadena vacía ("" , que es un String que no tiene ningún carácter) que decir que apunte a null (que no
es un String, sino una forma de indicar que no apunta a ningún objeto). La cadena vacía sí es un objeto.

La declaración e instanciación de un objeto puede realizarse en la misma instrucción, así:

String mensaje = new String ("El primer programa");

[Link] 20/65
25/12/2018 [Link]

4.4.- Manipulación.
Una vez creado e instanciado el objeto ¿cómo accedemos a su contenido?

Para acceder a los atributos y métodos del objeto utilizaremos el nombre del objeto seguido del operador punto (.) y el nombre del
atributo o método que queremos utilizar. Cuando utilizamos el operador punto se dice que estamos enviando un mensaje al objeto.
La forma general de enviar un mensaje a un objeto es:

[Link]

Por ejemplo, para acceder a las variables instancia o atributos se utiliza la siguiente sintaxis:

[Link]

Y para acceder a los métodos o funciones miembro del objeto se utiliza la sintaxis:

[Link]([parametro1, parametro2, ..., parametroN] )

En la sentencia anterior parametro1, parametro2, etc., son los parámetros que utiliza el método. Aparecen entre corchetes para indicar
que son opcionales, ya que puede haber métodos que no lleven parámetros.

Para entender mejor cómo se manipulan objetos vamos a utilizar un ejemplo. Para ello necesitamos la Biblioteca de Clases Java o
API (Application Programming Interface - Interfaz de programación de aplicaciones). Uno de los paquetes de librerías o bibliotecas es
[Link]. Este paquete contiene clases destinadas a la creación de objetos gráficos e imágenes. Vemos por ejemplo cómo crear un
rectángulo.

En primer lugar instanciamos el objeto utilizando el método constructor, que se llama igual que el objeto, e indicando los parámetros
correspondientes a la posición y a las dimensiones del rectángulo:

Rectangle rectangulo = new Rectangle(50, 50, 150, 150);

La sentencia anterior declara la variable rectangulo como una referencia de tipo Rectangle, y hace que apunte a un nuevo objeto que
se crea al invocar al constructor con el operador new. El constructor recibe como parámetros las coordenadas de la esquina superior
izquierda, que sería el punto (50, 50) en la pantalla, y el ancho y alto del mismo (longitud de la base y la altura), que sería 150 en
ambos casos.

Una vez instanciado el objeto rectangulo, si queremos cambiar el valor de los atributos utilizamos el operador punto. Por ejemplo,
para cambiar la dimensión del rectángulo, para que tanto su altura como su base sean 100, en lugar de los 150 que le habíamos
asignado, se haría modificando directamente el valor de sus atributos así::

[Link] = 100 ;
[Link] = 100 ;

O bien, podemos utilizar un método para hacer algo similar a lo anterior. Por ejemplo, la siguiente sentencia, fija el tamaño de
rectangulo a 200 por 200, tanto de base como de altura.

[Link](200,200) ;

A continuación puedes acceder al código del ejemplo:

Manipular objetos. (2 KB)

[Link] 21/65
25/12/2018 [Link]

Debes conocer
En el siguiente vídeo se explican los conceptos de clase y objeto y se pone un ejemplo de su uso.

Creación de clases y objetos en Java

Creación de clases en Java | | UPV

Resumen del vídeo

[Link] 22/65
25/12/2018 [Link]

4.5.- Destrucción de objetos y liberación de memoria.


Cuando un objeto deja de ser utilizado, es necesario liberar el espacio de memoria y otros recursos
que poseía para poder ser reutilizados por el programa. A esta acción se le denomina destrucción
del objeto.

En Java la destrucción de objetos corre a cargo del recolector de basura (garbage collector). ¡Un
gran invento!, ya que nos permite como programadores prácticamente desentendernos de ese asunto,
sabiendo además que nunca van a producirse problemas por olvidarse de recoger la basura
adecuadamente, como ocurría en otros lenguajes.
Pat Pilon
El recolector de basura es un sistema de destrucción automática de objetos que ya no son utilizados.
Lo que se hace es liberar una zona de memoria que había sido reservada previamente mediante el operador new, pero que ya ha
dejado de estar referenciada, es decir, ya no hay forma de llegar a ella, y por tanto ya no es posible volver a usar ese objeto. Esto
evita que al programar tengamos que preocuparnos de realizar la liberación de memoria.

El recolector de basura se ejecuta en segundo plano y de manera muy eficiente para no afectar a la velocidad del programa que se
está ejecutando. Lo que hace es que periódicamente va buscando objetos que ya no son referenciados, y cuando encuentra alguno
lo marca para ser eliminado. Después los elimina en el momento que considera oportuno, cuando el procesador está menos
ocupado.

Justo antes de que un objeto sea eliminado por el recolector de basura, se ejecuta su método finalize(). Si queremos forzar que se
ejecute el proceso de finalización de todos los objetos del programa podemos utilizar el método runFinalization() de la clase System.
La clase System forma parte de la Biblioteca de Clases de Java y contiene diversas clases para la entrada y salida de información,
acceso a variables de entorno del programa y otros métodos de diversa utilidad. Para forzar el proceso de finalización ejecutaríamos:

[Link]();

Autoevaluación

Las fases del ciclo de vida de un objeto son: Creación, Manipulación y Destrucción.

Verdadero Falso

Verdadero
Efectivamente, los objetos tienen un tiempo de vida limitado y esas son las fases que atraviesan durante su vida
útil.

[Link] 23/65
25/12/2018 [Link]

5.- Utilización de métodos.

Caso práctico
María está contenta con lo que está aprendiendo sobre Java, básicamente se trata de
ampliar sus conocimientos y con la experiencia que ella tiene no le resultará difícil
ponerse a programar en poco tiempo.

Juan ha comenzado el proyecto de la Clínica Veterinaria y ella quiere implicarse también


lo antes posible. Además, están los dos becarios Ana y Carlos, que se han incorporado
al proyecto hace poco y hay que comenzar a pensar en tareas para ellos.

Por lo pronto, María continúa con el documento facilitado por Juan, ahora tiene que ver
Seudonimoanonimo cómo se utilizan los métodos, aunque intuye que no va a ser algo muy diferente a las
funciones y procedimientos de cualquier otro lenguaje.

Los métodos, junto con los atributos, forman parte de la estructura interna de un objeto. Los
métodos contienen la declaración de variables locales y las operaciones que se pueden realizar
para el objeto, y que son ejecutadas cuando el método es invocado. Se definen en el cuerpo de
la clase y posteriormente son instanciados para convertirse en métodos de instancia de un
objeto.

Para utilizar los métodos adecuadamente es conveniente conocer la estructura básica de que
disponen.

Al igual que las clases, los métodos están compuestos por una cabecera y un cuerpo. La
cabecera también tiene modificadores, en este caso hemos utilizado public para indicar que el
método es público, lo cual quiere decir que le pueden enviar mensajes no sólo los métodos del
objeto sino los métodos de cualquier otro objeto externo. Veremos más adelante los
modificadores que se pueden usar y lo que significa cada uno.

Dentro de un método nos encontramos el cuerpo del método que contiene el código de la acción
a realizar. Las acciones que un método puede realizar son:

Inicializar los atributos del objeto.


Consultar los valores de los atributos.
Modificar los valores de los atributos.
Llamar a otros métodos, del mismo objeto o de objetos externos.

Citas para pensar


En cuestión de sentido común tomar un método y probarlo. Pero lo importante es probar algo.

Franklin Delano Roosevelt.

[Link] 24/65
25/12/2018 [Link]

5.1.- Parámetros y valores devueltos.


Los métodos se pueden utilizar tanto para consultar información sobre el objeto como para modificar su
estado. La información consultada del objeto se devuelve a través de lo que se conoce como valor de
retorno, y la modificación del estado del objeto, o sea, de sus atributos, se hace mediante la lista de
parámetros.

En general, la lista de parámetros de un método se puede declarar de dos formas diferentes:

Por valor. El valor de los parámetros no se devuelve al finalizar el método, es decir, cualquier
modificación que se haga en los parámetros no tendrá efecto una vez se salga del método. Esto es así
porque cuando se llama al método desde cualquier parte del programa, dicho método recibe una copia
de los argumentos, por tanto cualquier modificación que haga será sobre la copia, no sobre las variables
originales.
Por referencia. La modificación en los valores de los parámetros sí tienen efecto tras la finalización del Wendy House
método. Cuando pasamos una variable a un método por referencia lo que estamos haciendo es pasar la
dirección del dato en memoria, por tanto cualquier cambio en el dato seguirá modificado una vez que salgamos del método.

En el lenguaje Java, todas las variables se pasan por valor, excepto los objetos que se pasan por referencia. En Java, la
declaración de un método tiene dos restricciones:

En un método hay que indicar qué tipo de valor devuelve (o bien void). Este valor de retorno es el valor que devuelve el
método cuando termina de ejecutarse, al método o programa que lo llamó. Puede ser un tipo primitivo, un tipo referenciado o
bien el tipo void, que indica la ausencia de valor de retorno.
Un método tiene un número fijo de argumentos. Los argumentos son variables a través de las cuales se pasa información al
método desde el lugar del que se llame, para que éste pueda utilizar dichos valores durante su ejecución. Los argumentos
reciben el nombre de parámetros cuando aparecen en la declaración del método.

El valor de retorno es la información que devuelve un método tras su ejecución.

Según hemos visto en el apartado anterior, la cabecera de un método se declara como sigue:

public tipoDeDatoDevuelto nombreMetodo (listaDeParametros) // Cabecera<br />{ // Cuerpo del método<br />}<br />

Como vemos, el tipo de dato devuelto aparece después del modificador public y se corresponde con el valor de retorno. (Aunque la
declaración puede terminar en punto y coma, como se ve en el ejemplo anterior, lo normal es que además de la declaración de la
cabecera, incluyamos la definición completa del método, lo que significa poner las sentencias del cuerpo del método entre llaves,
justo en el lugar donde aparece el punto y coma en la sentencia anterior).

La lista de parámetros aparece al final de la cabecera del método, justo después del nombre, encerrados entre signos de paréntesis
y separados por comas. Se debe indicar el tipo de dato de cada parámetro así:

(tipoParametro1 nombreParametro1, ..., tipoParametroN nombreParametroN)

Cuando se llame al método, se deberá utilizar el nombre del método, seguido de los argumentos que deben coincidir con la lista de
parámetros.

La lista de argumentos en la llamada a un método (lista de parámetros actuales) debe coincidir en número, tipo y orden
con los parámetros incluidos en la declaración del método (lista de parámetros formales), ya que de lo contrario se
produciría un error de sintaxis.

[Link] 25/65
25/12/2018 [Link]

5.2.- Constructores.
¿Recuerdas cuando hablábamos de la creación e instanciación de un objeto?

Decíamos que utilizábamos el operador new seguido del nombre de la clase y un paréntesis. Además, el nombre de la clase era
realmente el constructor de la misma, de ahí la necesidad de poner paréntesis, y lo definíamos como un método especial que sirve
para inicializar valores. En este apartado vamos a ver un poco más sobre los constructores.

Un constructor es un método especial con el mismo nombre de la clase y que no devuelve ningún valor de forma
explícita tras su ejecución, aunque implícitamente devuelve el objeto que se está creando.

Cuando creamos un objeto debemos instanciarlo utilizando el constructor de la clase. Veamos la


clase Date proporcionada por la Biblioteca de Clases de Java. Si queremos instanciar un objeto a
partir de la clase Date tan sólo tendremos que utilizar el constructor seguido de un paréntesis:

Date fecha = new Date();

Con la anterior instrucción estamos creando un objeto fecha de tipo Date, que contendrá la fecha
y hora actual del sistema.

La estructura de los constructores es similar a la de cualquier método, salvo que no tiene que indicarse explícitamente el tipo de dato
devuelto porque ya está claro que lo que devuelve es el objeto que crea. Está formada por una cabecera y un cuerpo, que contiene
la inicialización de atributos y resto de instrucciones del constructor.

El método constructor tiene las siguientes particularidades:

El constructor es invocado automáticamente en la creación de un objeto, y sólo esa vez.


Los nombres de los constructores no empiezan con minúscula, como el resto de los métodos, ya que se llaman igual que
la clase y los nombres de clase deben empezar siempre con letra mayúscula, según convenio.
Puede haber varios constructores para una clase, que se llamarán todos igual, pero que se diferenciarán por su lista de
argumentos.
Como cualquier método, el constructor puede tener parámetros para definir qué valores dar a los atributos del objeto.
El constructor por defecto es aquél que no tiene argumentos o parámetros. Cuando creamos un objeto llamando al nombre
de la clase sin argumentos, estamos utilizando el constructor por defecto.
Es necesario que toda clase tenga al menos un constructor. Si no definimos constructores para una clase, y solamente en
ese caso, el compilador crea un constructor por defecto vacío, que inicializa los atributos a sus valores por defecto, según del
tipo que sean: 0 para los tipos numéricos, false para los boolean y null para las referencias. Dicho constructor lo que hace es
llamar al constructor sin argumentos de la superclase (clase de la cual hereda); si la superclase no tiene constructor sin
argumentos se produce un error de compilación.

Cuando definimos constructores personalizados, el constructor por defecto deja de existir, y si no definimos nosotros un constructor
sin argumentos cuando intentemos utilizar el constructor por defecto nos dará un error de compilación.

Autoevaluación
Marca las opciones que sean correctas.

Un constructor es un método que puede ser invocado en cualquier momento para un objeto, para que éste quede
reinicializado, con todos sus atributos a valores nulos: 0 para atributos numéricos, false para boolean, y null para
referencias.

El constructor debe llamarse, forzosamente, como la clase en la que está definido.

Es siempre obligatorio definir un constructor en una clase, ya que de lo contrario resultaría imposible crear
objetos de esa clase.

Una clase puede definir varios constructores, que obligatoriamente se llamarán todos igual, como la clase,
diferenciándose por su lista de parámetros. En caso de que hayamos declarado algún constructor personalizado
con parámetros en una clase, Java ya no creará implícitamente el constructor por defecto, que creaba el objeto
inicializándolo a valores nulos: 0 para atributos numéricos, false para boolean, y null para referencias.

[Link] 26/65
25/12/2018 [Link]

Mostrar retroalimentación

Solución

1. Incorrecto
2. Correcto
3. Incorrecto
4. Correcto

[Link] 27/65
25/12/2018 [Link]

5.3.- El operador this.


Los constructores y métodos de un objeto suelen utilizar el operador this. Este operador sirve para referirse a los atributos de un
objeto cuando estamos dentro de él. Sobre todo se utiliza cuando existe ambigüedad entre el nombre de un parámetro y el nombre
de un atributo, entonces en lugar del nombre del atributo solamente escribiremos [Link], y así no habrá duda de a qué
elemento nos estamos refiriendo.

De hecho, se aconseja no inventarse nombres distintos para los parámetros que se usan para recoger el valor que se va a
asignar a un atributo, es preferible llamarle igual a dos cosas que en el fondo se refieren al mismo atributo, y distinguir
parámetro y atributo por medio del operador this.

Vamos a ilustrar mediante un ejemplo la utilización de objetos y métodos, así como el uso de parámetros y el operador this. Aunque
la creación de clases la veremos en las siguientes unidades, en este ejercicio creamos una pequeña clase para que podamos
instanciar el objeto con el que vamos a trabajar.

Las clases se suelen representar como un rectángulo, y dentro de él se sitúan los atributos y los métodos de dicha clase.

En la imagen, la clase Pajaro está compuesta por tres atributos, uno de ellos el nombre y otros dos que indican la posición del ave,
posX y posY. Tiene dos métodos constructores y un método volar(). Como sabemos, los métodos constructores reciben el mismo
nombre de la clase, y puede haber varios para una misma clase, dentro de ella se diferencian unos de otros por los parámetros que
utilizan.

Ejercicio resuelto
Dada una clase principal llamada Pajaro, se definen los atributos y métodos que aparecen en la imagen. Los métodos
realizan las siguientes acciones:

Pajaro(). Constructor por defecto. En este caso, el constructor por defecto no contiene ninguna instrucción, ya
que Java inicializa de forma automática las variables miembro, si no le damos ningún valor.
Pajaro(String nombre, int posX, int posY). Constructor que recibe como argumentos una cadena de texto y dos
enteros para inicializar el valor de los atributos.
volar(int posX, int posY). Método que recibe como argumentos dos enteros: posX y posY, y devuelve un valor de
tipo double como resultado, usando la palabra clave return. El valor devuelto es el resultado de aplicar un
desplazamiento de acuerdo con la siguiente fórmula:

Diseña un programa que utilice la clase Pajaro, cree una instancia de dicha clase y ejecute sus métodos.

Mostrar retroalimentación

Lo primero que debemos hacer es crear la clase Pajaro, con sus métodos y atributos. De acuerdo con los datos
que tenemos, el código de la clase sería el siguiente:

Debemos tener en cuenta que se trata de una clase principal, lo cual quiere decir que debe contener un método
main() dentro de ella. En el método main() vamos a situar el código de nuestro programa.
Sin embargo, debes tener en cuenta que ésta no es la forma más correcta de hacerlo y que el método main()
debería estar en otra clase. Es mucho mejor separar la definición de la clase Pajaro , que quedaría como una
definición de un tipo de datos, de lo que es el uso de esa clase creando y manipulando objetos, que sería lo que
se haría desde el método main() alojado en otra clase, que sería la clase principal del programa. La idea es
simple si piensas en String: la clase String define un tipo de dato (valores que puede tomar, y operaciones que
pueden hacerse con ellos), pero no dispone de ningún método main(), por lo que será la clase principal de
nuestra aplicación, para la que nosotros creamos el método main(), la que definirá objetos de tipo String y los
manipulará haciendo usos de los métodos definidos en String, pero desde dentro del método main() de nuestra
clase principal.
El ejercicio dice que tenemos que crear una instancia de la clase y ejecutar sus métodos, entre los que están el
constructor y el método volar(). También es conveniente imprimir el resultado de ejecutar el método volar(). Por

[Link] 28/65
25/12/2018 [Link]
tanto, lo que haría el programa sería:

Crear un objeto de la clase e inicializarlo.


Invocar al método volar.
Imprimir por pantalla la distancia recorrida.

Para inicializar el objeto utilizaremos el constructor con parámetros, después ejecutaremos el método volar() del
objeto creado y finalmente imprimiremos el valor que nos devuelve el método. El código de la clase main()
quedaría como sigue:

Si ejecutamos nuestro programa el resultado sería el siguiente:

Si quieres acceder al archivo completo del ejercicio puedes utilizar el siguiente enlace:

Ejercicio resuelto clase Pajaro (2 KB)

[Link] 29/65
25/12/2018 [Link]

5.4.- Métodos estáticos.


Cuando trabajábamos con cadenas de caracteres utilizando la clase String, veíamos las
operaciones que podíamos hacer con ellas: obtener longitud, comparar dos cadenas de
caracteres, cambiar a mayúsculas o minúsculas, etc. Pues bien, sin saberlo estábamos
utilizando métodos estáticos definidos por Java para la clase String. Pero ¿qué son los métodos
estáticos? Veámoslo.

Los métodos estáticos son aquellos métodos definidos para una clase que se pueden usar
directamente, sin necesidad de crear un objeto de dicha clase. También se llaman métodos de
clase.

Para llamar a un método estático, podemos hacerlo de distintas formas:

El nombre del método, si lo llamamos desde la misma clase en la que se encuentra definido.

nombreMetodoEstatico();

El nombre de la clase, seguido por el operador punto (.) más el nombre del método estático, si lo llamamos desde una clase
distinta a la que se encuentra definido. Esta será la forma habitual de usar los métodos estáticos:

[Link]();

El nombre del objeto, seguido por el operador punto (.) más el nombre del método estático. Esta forma se podría usar cuando
tengamos un objeto instanciado de la clase en la que se encuentra definido el método estático, pero siempre será preferible
invocarlo mediante el nombre de la clase, ya que al invocarlo con un objeto, da la sensación de que es "un mensaje para
ese objeto", que hace algo exclusivamente con ese objeto, cuando en realidad hace algo para la clase, para todos los objetos
de la clase:

[Link]();

Es muy recomendable que cualquier método estático se invoque siempre referenciado por el nombre de la clase
en la que está definido, (tanto si se invocan desde la misma clase, como si se invocan desde una clase distinta,
como si existen objetos de la clase con los que se podría invocar si se quisiera), justamente para hacer explícito
que se trata de un método estático sin más que ver la sentencia donde se invoca, quedando claro que hace algo
para la clase, y no para un objeto particular. Es decir, como:

[Link]();

Los métodos estáticos no afectan al estado de los objetos instanciados de la clase (variables de instancia), y suelen utilizarse para
realizar operaciones comunes a todos los objetos de la clase. Por ejemplo, si necesitamos contar el número de objetos
instanciados de una clase, podríamos utilizar un método estático que fuera incrementando el valor de una variable entera de la clase
conforme se van creando los objetos. Además, podría haber un método para consultar ese total de objetos creado, y debería ser
estático, porque yo podría querer consultar el número de elementos que existen mediante ese método, incluso en el caso de que
no existiera ningún objeto de dicha clase que poder usar para invocar al método. Mediante el nombre de la clase sí podría al ser
estático.

En la Biblioteca de Clases de Java existen muchas clases que contienen métodos estáticos. Pensemos en las clases que ya hemos
utilizado en unidades anteriores, como hemos comentado la clase String con todas las operaciones que podíamos hacer con ella y
con los objetos instanciados a partir de ella. O bien la clase Math. para la conversión de tipos de datos. Todos ellos son métodos
estáticos que la API de Java define para esas clases. Lo importante es que tengamos en cuenta que al tratarse de métodos
estáticos, para utilizarlos no necesitamos crear un objeto de dichas clases.

Autoevaluación

Los métodos estáticos, también llamados métodos de instancia, suelen utilizarse para realizar operaciones
comunes a todos los objetos de la clase.

Verdadero Falso

Falso

[Link] 30/65
25/12/2018 [Link]
Los métodos estáticos no son métodos de instancia porque se pueden utilizar directamente, referenciándolos
con el nombre de la clase a la que pertenecen, sin necesidad de crear un objeto de la clase para ello.

[Link] 31/65
25/12/2018 [Link]

6.- Librerías de objetos (paquetes).

Caso práctico
—¡Vaya! -exclama María- No consigo encontrar la clase Persona dentro del conjunto de
clases que hasta ahora he creado.

—¿Por qué no pruebas a dividir las clases en paquetes? -pregunta Juan-. En un


paquete agrupas las que estén relacionadas, y así te será más fácil encontrar una clase
la próxima vez. Además puedes crear paquetes dentro de otros, como si fuera una
estructura de directorios.

—¿Ah sí? Pues es justo lo que necesito para resolver este desorden. Voy a ponerme
JJ Merelo con ello -añade María.

Conforme nuestros programas se van haciendo más grandes, el número de clases va creciendo. Meter todas las clases en único
directorio no ayuda a que estén bien organizadas, lo mejor es hacer grupos de clases, de forma que todas las clases que estén
relacionadas o traten sobre un mismo tema estén en el mismo grupo.

Un paquete de clases es una agrupación de clases que consideramos que están relacionadas entre sí o tratan de
un tema común.
Las clases de un mismo paquete tienen un acceso privilegiado a los atributos y métodos de otras clases de dicho
paquete, una especie de "relación de confianza". Es por ello por lo que los paquetes son también, en cierto modo,
unidades de encapsulación y ocultación de información.

Java nos ayuda a organizar las clases en paquetes. En cada fichero .java que hagamos, al principio,
podemos indicar a qué paquete pertenece la clase que hagamos en ese fichero.

Los paquetes se declaran utilizando la palabra clave package seguida del nombre del paquete. Para
establecer el paquete al que pertenece una clase hay que poner una sentencia de declaración como la
siguiente al principio de la clase:

package Nombre_de_Paquete;
Seth Schoen

Por ejemplo, si decidimos agrupar en un paquete "ejemplos" un programa llamado "Bienvenida", pondríamos en nuestro fichero
[Link] lo siguiente:

El código es exactamente igual que como hemos venido haciendo hasta ahora, solamente hemos añadido la línea "package
ejemplos;" al principio. En la imagen se muestra cómo aparecen los paquetes en el entorno integrado de Netbeans.

Debes conocer
En el siguiente fichero puedes ver una demostración de cómo hemos creado el proyecto Bienvenida:

Crear proyecto con NetBeans. (530 KB)

[Link] 32/65
25/12/2018 [Link]

6.1.- Sentencia import.


Cuando queremos utilizar una clase que está en un paquete distinto a la clase que estamos
utilizando, se suele utilizar la sentencia import. Por ejemplo, si queremos utilizar la clase Scanner que
está en el paquete [Link] de la Biblioteca de Clases de Java, tendremos que utilizar esta sentencia:

import [Link];
npslibrarian

Se pueden importar todas las clases de un paquete con una sentencia import. Por ejemplo, para importar todas las clases del
paquete [Link], se puede hacer así:

import [Link].*;

Es importante aclarar que usando el asterisco, importamos las clases del paquete, pero NO se importan las clases de los
subpaquetes que pudiera tener.

Las sentencias import (puede haber varias) deben aparecer al principio de la clase, justo después de la sentencia package, si ésta
existiese.

También podemos utilizar una clase sin importarla con la sentencia import, en cuyo caso cada vez que queramos usarla debemos
indicar su ruta completa:

[Link] teclado = new [Link] ([Link]);

Reflexiona
En unidades anteriores hemos hecho uso de clases como String, o Math, que si consultamos en la documentación de la
API, pertenecen al paquete [Link] y sin embargo, nunca hemos tenido que usar ninguna sentencia import
[Link]; ni import [Link]; ni tampoco import [Link].*; y a pesar de ello todo funcionaba
correctamente.

¿No habíamos quedado en que siempre había que importar las clases de otros paquetes que quisiéramos usar?

Por otra parte, ¿qué es preferible, importar las clases una a una o importar todas las clases del paquete usando el
asterisco?

Mostrar retroalimentación

En principio es así, cuando se quiere usar una clase de otro paquete, hay que indicarlo expresamente con una
sentencia import, pero el paquete [Link] es una excepción. Este paquete contiene una serie de clases tan
importantes, que sin él sería imposible hacer nada en Java, ya que contiene, por ejemplo, la propia clase Object,
de la que heredan todas las demás clases, y también toda una serie de clases de uso tan frecuente, que sería
realmente tedioso y molesto tener que ir importándolas cada vez que se van a usar, lo que supondría
importarlas prácticamente siempre, como es el caso de por ejemplo, String. Por eso Java nos ahorra el trabajo e
importa implícitamente todas las clases de ese paquete, lo que nos permite usarlas sin preocuparnos de hacer
nada más.
Respecto a la segunda cuestión, vamos a responderla con una especie de FAQ sobre el uso de import, que
pueden ayudar a entender mejor su funcionamiento.

¿Importar las clases hace que mi archivo (.class o .jar) sea más largo?No, la sentencia import sólo
proporciona al compilador una ruta donde ir a buscar las clases cuando las necesita.
¿Es menos eficiente importar todas las clases de un paquete usando .* que importar sólo las que
vaya a usar con una sentencia import para cada una?No. La búsqueda de nombres es muy eficiente y no
hay diferencia práctica, dado que "no se importa nada realmente", sólo se indica la ruta donde buscar, y si es
la misma para toda una serie de clases, es suficiente con poner la ruta para todas, en lugar de poner la ruta
una a una.
¿No queda mejor documentado el código si se usan import distintos para importar cada clase de
forma individual?Podría parecer que sí, pero la realidad es que NO, porque tiene una serie de desventajas:
Es "duro" acordarse de borrar las clases de la lista cuando dejen de usarse en futuras versiones de un
programa, por lo que puede darse el caso de que una clase que ha dejado de usarse siga teniendo su
sentencia import, por lo que en este caso, al verlo, si vamos a buscar qué se hace con esa clase que
ha dejado de usarse nos podemos volver locos, así que en vez de una ayuda a la documentación
puede acabar siendo un error de documentación.
Importar explícitamente una única clase permite que "accidentalmente" pueda definir clases propias
cuyos nombres entran en conflicto con los nombres de las clases en las librerías estándar, lo cual es
[Link] 33/65
25/12/2018 [Link]
poco deseable. Usando un import para todo un paquete con .* , ayudamos en realidad a prevenir ese
accidente.
Si ya he importado, por ejemplo, [Link].*, ¿por qué tengo que importar también [Link].*?La
sentencia import con la plantilla * sólo establece una ruta, que sólo permite importar las clases de esa ruta
(ese paquete) y no los subpaquetes, que serían rutas distintas. (Piensa que es como si cada paquete fuera
una carpeta, que puede tener subcarpetas).
¿Por qué no necesito usar un import con las clases String, System, Math, etc.?Esto ya se explicó con
más detalle al comienzo, pero resumidamente, esas clases están en el paquete [Link], que contiene
clases tan importantes y necesarias que el lenguaje las incluye por defecto, sin necesidad de usar
explícitamente import.
¿Es importante el orden en que se escriban las sentencias import?No lo es. Sólo es aconsejable
intentar escribirlas de forma que sean más legibles. Por ejemplo, agrupando los import que tengan cierta
relación, etc.

Para saber más


Te proponemos el siguiente enlace para repasar conceptos que hemos visto a lo largo de la unidad sobre programación
orientada a objetos y utilización de clases:

Tutorial de Java en español- Capítulo 13 – Clases y Objetos.

Tutorial Java en Español - Capitulo 13 - Clases y Objetos - …

Resumen textual para el vídeo "Tutorial de Java en español- Capítulo 13 – Clases y Objetos".
La siguiente parte del vídeo habla sobre la utilización de objetos y clases en Java:

Tutorial de Java en español- Capítulo 14 – Clases y Objetos.

Tutorial Java en Español - Capitulo 14 - Clases y Objetos - …

Resumen textual para el vídeo "Tutorial de Java en español- Capítulo 14 – Clases y Objetos."

Autoevaluación

Es preferible importar todas las clases que necesitemos mediante su propia sentencia import, ya que si
usamos .* estaremos añadiendo a nuestra aplicación el código de toda una serie de clases del paquete que no
necesitamos, y que sólo servirán para aumentar el tamaño de la aplicación, alargando el tiempo de
compilación, además.

Verdadero Falso

[Link] 34/65
25/12/2018 [Link]

Falso
La sentencia import "no importa código" a nuestra aplicación, ni aumenta el tamaño de la misma. Sólo aporta
una referencia al compilador para que sepa dónde tiene que ir a buscar las clases cuando lo necesite, pero
hasta ese momento, no añade nada.

[Link] 35/65
25/12/2018 [Link]

6.2.- Compilar y ejecutar clases con paquetes.


Hasta aquí todo correcto. Sin embargo, al trabajar con paquetes, Java nos obliga a organizar los
directorios, compilar y ejecutar de cierta forma para que todo funcione adecuadamente.

Si hacemos que [Link] pertenezca al paquete ejemplos, debemos crear un subdirectorio


"ejemplos" y meter dentro el archivo [Link].

Por ejemplo, en Linux tendríamos esta estructura de directorios:

Tom
/<directorio_usuario>/Proyecto_Bienvenida/ejemplos/[Link]

Debemos tener cuidado con las mayúsculas y las minúsculas, para evitar problemas, tenemos que poner el nombre en "package"
exactamente igual que el nombre del subdirectorio.

Para compilar la clase [Link] que está en el paquete ejemplos debemos situarnos en el directorio padre del paquete y
compilar desde ahí:

$ cd /<directorio_usuario>/Proyecto_Bienvenida
$ javac ejemplos/[Link]

Si todo va bien, en el directorio ejemplos nos aparecerá la clase compilada [Link].

Flor Moncada. Montaje sobre captura de pantalla en Ubuntu.


Para ejecutar la clase compilada [Link] que está en el directorio ejemplos, debemos seguir situados en el directorio padre
del paquete. El nombre completo de la clase es "[Link]", es decir "[Link]". Los pasos serían los siguientes:

$ cd /<directorio_usuario>/Proyecto_Bienvenida
$ java ejemplos/Bienvenida
Bienvenido a Java

Si todo es correcto, debe salir el mensaje "Bienvenido a Java" por la pantalla.

Afortunadamente, si el proyecto lo hemos creado desde un entorno integrado como Netbeans, podemos delegar en que
será el entorno quien se encargue de estos detalles, la compilación y ejecución se realizará al ejecutar la opción Run File
(Ejecutar archivo) o hacer clic sobre el botón Ejecutar de la barra de herramientas.

[Link] 36/65
25/12/2018 [Link]

6.3.- Jerarquía de paquetes.


Para organizar mejor las cosas, un paquete también puede contener otros paquetes. Es decir,
podemos hacer subpaquetes de los paquetes y subpaquetes de los subpaquetes y así
sucesivamente. Piensa que internamente Java asocia una carpeta a cada paquete, así que podemos
tener cualquier jerarquía que paquetes, de la misma forma que podemos tener cualquier jerarquía de
carpetas. Esto permite agrupar paquetes relacionados en un paquete más grande. Por ejemplo, si
quiero dividir mis clases de ejemplos en ejemplos básicos y ejemplos avanzados, puedo poner más
niveles de paquetes separando por puntos:

[Link]
package [Link];
package [Link];

A nivel de sistema operativo, tendríamos que crear los subdirectorios basicos y avanzados dentro del directorio ejemplos, y meter ahí
las clases que correspondan.

Para compilar, en el directorio del proyecto habría que compilar poniendo todo el path hasta llegar a la clase. Es decir, el nombre de
la clase va con todos los paquetes separados por puntos, por ejemplo [Link].

La estructura de directorios en el sistema operativo cuando usamos subpaquetes sería:

/<directorio_usuario>/Proyecto_Bienvenida/ejemplos/basicos/[Link]

Y la compilación y ejecución sería:

$ cd /<directorio_usuario>/Proyecto_Bienvenida
$ javac ejemplos/basicos/[Link]
$ java ejemplos/basicos/Bienvenida
Hola Mundo

Flor Moncada. Montaje sobre captura de pantalla en Ubuntu.

La Biblioteca de Clases de Java se organiza haciendo uso de esta jerarquía de paquetes. Así por ejemplo, si quiero acceder a la
clase Date, tendré que importarla indicando su ruta completa, o sea, [Link], así:

import [Link];

Citas para pensar

Tan bueno como es heredar una biblioteca, es mejor coleccionar una. Augustine Birrel.

[Link] 37/65
25/12/2018 [Link]

6.4.- Librerías Java.

Cuando descargamos el entorno de compilación y ejecución de Java, obtenemos la API de Java.


Como ya sabemos, se trata de un conjunto de bibliotecas que nos proporciona paquetes de clases
útiles para nuestros programas.

Utilizar las clases y métodos de la Biblioteca de Java nos va ayudar a reducir el tiempo de desarrollo
considerablemente, por lo que es importante que aprendamos a consultarla y conozcamos las clases
más utilizadas.

Los paquetes más importantes que ofrece el lenguaje Java son:

[Link]. Contiene las clases que gestionan la entrada y salida, ya sea para manipular ficheros, leer o escribir en pantalla, en
memoria, etc. Este paquete contiene por ejemplo la clase BufferedReader que se utiliza para la entrada por teclado.
[Link]. Contiene las clases básicas del lenguaje. Este paquete no es necesario importarlo, ya que es importado
automáticamente por el entorno de ejecución. En este paquete se encuentra la clase Object, que sirve como raíz para la
jerarquía de clases de Java, o la clase System que ya hemos utilizado en algunos ejemplos y que representa al sistema en el
que se está ejecutando la aplicación. También podemos encontrar en este paquete las clases que "envuelven" los tipos
primitivos de datos, como Integer, Long, Float, Double, etc., lo que proporciona una serie de métodos para cada tipo de dato de
utilidad, como por ejemplo métodos para las conversiones de datos.
[Link]. Biblioteca de clases de utilidad general para el programador. Este paquete contiene por ejemplo la clase Scanner
utilizada para la entrada por teclado de diferentes tipos de datos, la clase Date, para el tratamiento de fechas, etc.
[Link]. Contiene herramientas para manipulaciones matemáticas.
[Link]. Incluye las clases relacionadas con la construcción de interfaces de usuario, es decir, las que nos permiten construir
ventanas, cajas de texto, botones, etc. Algunas de las clases que podemos encontrar en este paquete son Button, TextField,
Frame, Label, etc.
[Link]. Contiene otro conjunto de clases para la construcción de interfaces avanzadas de usuario. Los componentes que se
engloban dentro de este paquete se denominan componentes Swing, y suponen una alternativa mucho más potente que AWT
para construir interfaces de usuario.
[Link]. Conjunto de clases para la programación en la red local e Internet.
[Link]. Contiene las clases necesarias para programar en Java el acceso a las bases de datos.
[Link]. Biblioteca de clases para implementar mecanismos de seguridad.

Como se puede comprobar, Java ofrece una completa jerarquía de clases organizadas a través de paquetes.

Para saber más


En el siguiente enlace puedes acceder a la información oficial sobre la Biblioteca de Clases de Java (está en Inglés).

Información oficial sobre la Biblioteca de Clases de Java.

En el siguiente vídeo se explica de manera interesante el paquete básico [Link]:

Clases que componen el paquete [Link].

Conoce mejor un paquete: [Link]

Resumen textual para "Clases que componen el paquete [Link]"

[Link] 38/65
25/12/2018 [Link]

7.- Programación de la consola: entrada y salida de


la información.

Caso práctico
Juan va a realizar algunas pruebas con el proyecto de la Clínica Veterinaria. Le comenta a María
que lo que tienen ahora mismo es la estructura básica del proyecto, que básicamente se trata de
la definición de algunas clases y objetos que se van a utilizar. Van a necesitar introducir datos por
pantalla para ver cómo se comportan esos objetos, y mostrar por pantalla el resultado de
manipularlos. Para ello utilizarán las clases System y Scanner.

—Estas clases ya las hemos utilizado anteriormente, están en los paquetes [Link] y [Link],
respectivamente, observa en el siguiente código cómo las utilizo —dice Juan.

—De acuerdo, enséñame ese código —comenta María.

Peter Megyeri

Los programas a veces necesitan acceder a los recursos del sistema, como por ejemplo los
dispositivos de entrada/salida estándar, para recoger datos de teclado o mostrar datos por
pantalla.

En Java, la entrada por teclado y la salida de información por pantalla se hace mediante la clase
System del paquete [Link] de la Biblioteca de Clases de Java.

Como cualquier otra clase, está compuesta de métodos y atributos. Los atributos de la clase
System son tres objetos que se utilizan para la entrada y salida estándar. Estos objetos son los siguientes:

[Link]. Entrada estándar: teclado.


[Link]. Salida estándar: pantalla.
[Link]. Salida de error estándar que se utiliza para mostrar mensajes de error. Una práctica común en informática es enviar
los mensajes de error a un dispositivo de salida diferente al de los mensajes normales. Los mensajes normales se envían a lo
que se llama "salida estándar". Los mensajes de error se envían a "error estándar".

No se pueden crear objetos a partir de la clase System, sino que se utiliza directamente llamando a cualquiera de sus métodos con el
operador de manipulación de objetos, es decir, el operador punto (.):

[Link]("Bienvenido a Java");

Para saber más


En el siguiente enlace puedes consultar los atributos y métodos de la clase System del paquete [Link] perteneciente
a la Biblioteca de Clases de Java:

Clase System de Java.

Autoevaluación

La clase System del paquete [Link], como cualquier clase, está formada por métodos y atributos, y además es
una clase que no se puede instanciar, sino que se utiliza directamente.

Verdadero Falso

Falso

[Link] 39/65
25/12/2018 [Link]
La clase System pertenece al paquete [Link].

[Link] 40/65
25/12/2018 [Link]

7.1.- Conceptos sobre la clase System.


La lectura por teclado es muy importante cuando empezamos a hacer nuestros primeros
programas. Para entender mejor en qué consiste la clase System, y en particular el objeto
[Link] vamos a describirlo más detenidamente.

En el apartado anterior hemos dicho que [Link] es un atributo de la clase System, que está
dentro del paquete [Link]. Pero además, si consultamos la Biblioteca de Clases de Java, nos
damos cuenta de que es un objeto, y como todos los objetos debe ser instanciado. En efecto,
volviendo a consultar la biblioteca de clases nos damos cuenta que [Link] es una instancia Flor Moncada. Captura de pantalla de
la web de Oracle. © (cita)
de una clase de Java que se llama InputStream.

En Java, InputStream nos permite leer en bytes, desde teclado, un archivo o cualquier otro dispositivo de entrada. Con esta clase
podemos utilizar por ejemplo el método read() que permite leer un byte de la entrada o skip(long n), que salta n bytes de la entrada.
Pero lo que realmente nos interesa es poder leer texto o números, no bytes, para hacernos más cómoda la entrada de datos. Para
ello se utilizan las clases:

InputStreamReader. Convierte los bytes leídos en caracteres. Particularmente, nos va a servir para convertir el objeto [Link]
en otro tipo de objeto que nos permita leer caracteres.
BufferedReader. Lee hasta un fin de línea. Esta es la clase que nos interesa utilizar, pues tiene un método readLine() que nos
va a permitir leer caracteres hasta el final de línea.

La forma de instanciar estas clases para usarlas con [Link] es la siguiente:

InputStreamReader isr = new InputStreamReader([Link]);


BufferedReader br = new BufferedReader (isr);

En el código anterior hemos creado un InputStreamReader a partir de [Link] y pasamos


dicho InputStreamReader al constructor de BufferedReader. El resultado es que las lecturas que
hagamos con el objeto br son en realidad realizadas sobre [Link], pero con la ventaja de que podemos leer una línea completa.
Así, por ejemplo, si escribimos una A, con:

String cadena = [Link]();

Obtendremos en cadena una "A".

Sin embargo, seguimos necesitando hacer la conversión si queremos leer números. Por ejemplo, si escribimos un entero 32, en
cadena obtendremos "32". Si recordamos, para convertir cadenas de texto a enteros se utiliza el método estático parseInt() de la
clase Integer, con lo cual la lectura la haríamos así:

int numero = [Link] ([Link]());

Esa operación de conversión de cadena a número sólo funcionará si la cadena introducida realmente se puede convertir en número,
porque representaba a un literal correcto para el tipo numérico de que se trata, en el caso de la sentencia anterior sería int. En caso
contrario, se produciría una excepción de tipo NumberFormatException, (Excepción de Formato de número) que debe ser capturada
y tratada convenientemente.

[Link] 41/65
25/12/2018 [Link]

7.2.- Entrada por teclado. Clase System.

A continuación vamos a ver un ejemplo de cómo utilizar la clase System para la entrada de datos por
teclado en Java.

Como ya hemos visto en unidades anteriores, para compilar y ejecutar el ejemplo puedes utilizar las
órdenes javac y java, o bien crear un nuevo proyecto en Netbeans y copiar el código que se proporciona en
el archivo anterior.

Código de entrada por teclado con la clase System.(4 KB)

Observa que hemos metido el código entre excepciones try-catch. Cuando en nuestro programa falla algo, por ejemplo la conversión
de un String a int, Java nos avisa lanzando excepciones. Si "capturamos" esa excepción en nuestro programa, podemos avisar al
usuario de qué ha pasado. Esto es conveniente porque si no tratamos la excepción seguramente el programa se pare y no siga
ejecutándose. El control de excepciones ya lo vimos en la unidad anterior, así que no creo que tengas ningún problema para
entender eso.

Para saber más


Te proponemos el siguiente enlace con un descriptivo vídeo sobre cómo capturar datos desde el teclado:

Capturar datos desde teclado con BufferedReader.

Capturando desde el teclado con BufferedReader

Resumen textual para "Capturar datos desde teclado con BufferedReader

[Link] 42/65
25/12/2018 [Link]

7.3.- Entrada por teclado. Clase Scanner.


La entrada por teclado que hemos visto en el apartado anterior tiene el inconveniente de que
sólo podemos leer de manera fácil tipos de datos String. Si queremos leer otros tipos de datos
deberemos convertir la cadena de texto leída en esos tipos de datos.

El kit de desarrollo de Java, a partir de su versión 1.5, incorpora la clase [Link], la cual Flor Moncada.
Captura de pantalla de la web copyright de Oracle.
permite leer tipos de datos String, int, long, etc., a través de la consola de la aplicación. Por
ejemplo, para leer un dato de tipo entero por teclado sería:

Scanner teclado = new Scanner ([Link]);


int i = [Link] ();

O bien esta otra instrucción para leer una línea completa, incluido texto, números o lo que sea:

String cadena = [Link]();

En las instrucciones anteriores hemos creado un objeto de la clase Scanner llamado teclado
utilizando el constructor de la clase, al cual le hemos pasado como parámetro la entrada básica del
sistema [Link] que por defecto está asociada al teclado.

Para conocer cómo funciona un objeto de la clase Scanner te proporcionamos el siguiente ejemplo:

Código de entrada por teclado con la clase Scanner.(2 KB)

Para saber más


Si quieres conocer algo más sobre la clase Scanner puedes consultar el siguiente enlace:

Capturar datos desde teclado con Scanner.

[Link] 43/65
25/12/2018 [Link]

7.4.- Salida por pantalla.


La salida por pantalla en Java se hace con el objeto [Link]. Este objeto es una instancia de
la clase PrintStream del paquete [Link]. Si miramos la API de PrintStream obtendremos la
variedad de métodos para mostrar datos por pantalla, algunos de estos son:

void print(String s): escribe una cadena de texto.


void println(String x): escribe una cadena de texto y termina la línea.
void printf(String format, Object... args): escribe una cadena de texto utilizando formato.

En la orden print() y println(), cuando queramos escribir un mensaje y el valor de una variable
Flor Moncada.
debemos utilizar el operador de concatenación de cadenas (+), por ejemplo: Captura de pantalla de la web copyright de Oracle.

[Link](“Bienvenido, “ + nombre);

Escribe el mensaje de "Bienvenido, Carlos", si el valor de la variable nombre es Carlos.

Las órdenes print() y println() consideran como cadenas de texto sin formato a todas las variables que escriben; por ejemplo, no
sería posible indicar que escriba un número decimal con dos cifras decimales o redondear las cifras, o escribir los puntos de los
miles. Para ello se utiliza la orden printf().

La orden printf() utiliza unos códigos de conversión para indicar de qué tipo es el contenido a mostrar. Estos códigos se caracterizan
porque llevan delante el símbolo %, algunos de ellos son:

%c : escribe un carácter.
%s : escribe una cadena de texto.
%d : escribe un entero.
%f : escribe un número en punto flotante.
%e : escribe un número en punto flotante en notación científica.

Por ejemplo, si queremos escribir el número float 12345.1684 con el punto de los miles y sólo dos cifras decimales la orden sería:

[Link]("% ,.2f", 12345.1684);

Esta orden mostraría el número 12.345,17 por pantalla.

Es importante aclarar que estos códigos de conversión formatean la salida, mostrándola de una manera o de otra, pero no
cambian el valor que internamente tengan las variables. Si en el caso anterior, en lugar de imprimir un valor concreto,
12345.1684, se hubiera impreso una variable con ese mismo valor, aunque se mostrara su valor como 12.345,17 por
pantalla, la variable seguiría teniendo almacenado el valor 12345.1684

Estas órdenes pueden utilizar las secuencias de escape que vimos en unidades anteriores, como " " para crear un salto de línea, " "
para introducir un salto de tabulación en el texto, etc.

Debes conocer
Para conocer algo más sobre la orden printf(), en el siguiente enlace tienes varios ejemplos de utilización:

Salida de datos con la orden printf().

Entrada y salida de datos.

Para saber más


En este otro enlace, puedes ver un ejemplo interesante de uso de la clase Scanner junto con las órdenes printf() y
println(). Para ello, descárgate el fichero, descomprímelo y haz doble clic en el fichero .html

Ejemplo de entrada y salida de datos (67 KB).

[Link] 44/65
25/12/2018 [Link]

7.5.- Salida de error.


La salida de error está representada por el objeto [Link]. Este objeto es también una instancia de
la clase PrintStream, por lo que podemos utilizar los mismos métodos vistos anteriormente.

La separación o diferencia entre la salida estándar y la de error se puede utilizar para redirigir los
mensajes de error a un lugar diferente que los mensajes normales.

Por defecto, tanto out como err tienen su destino en la misma pantalla, o al menos en el caso de la
consola del sistema donde las dos salidas son representadas con el mismo color y no notamos
diferencia alguna. En cambio, en la consola de varios entornos integrados de desarrollo como
NetBeans o Eclipse la salida de err se ve en un color diferente. Teniendo el siguiente código: Ameya arsekar

La salida de este ejemplo en NetBeans es:

Como vemos, en un entorno como NetBeans, utilizar las dos salidas nos puede ayudar a una mejor depuración del código.

Aunque por defecto vemos la salida de error en la consola, es posible redirigirla a un fichero por ejemplo, como podemos ver en el
siguiente para saber más.

Para saber más


Más información sobre la entrada, salida y error estándar.

Flujos de datos estándar.

Autoevaluación
Relaciona cada clase con su función, escribiendo el número asociado a la función en el hueco
correspondiente.

Ejercicio de relacionar

Clase. Relación. Función.

Scanner 1. Convierte los bytes leídos en caracteres.

PrintStream 2. Lee hasta un fin de línea.

InputStreamReader 3. Lee diferentes tipos de datos desde la consola de la aplicación.

BufferedReader 4. Contiene varios métodos para mostrar datos por pantalla.

Enviar

PrintStream se utiliza para la salida de datos por pantalla y las otras clases, para la entrada de datos por
teclado.

[Link] 45/65
25/12/2018 [Link]

8.- Excepciones.

Caso práctico
Para que las aplicaciones desarrolladas por BK Programación mantengan una
valoración positiva a lo largo del tiempo por parte de sus clientes, es necesario que
éstas no se vean comprometidas durante su ejecución. Hay innumerables ocasiones en
las que programas que aparentemente son formidables (por su interfaz, facilidad de
uso, etc.) comienzan a generar errores en tiempo de ejecución que hacen que el
usuario desconfíe de ellos día a día.

Para evitar estas situaciones, Ada va a fomentar en María y Juan la cultura de la


detección, control y solución de errores a través de las poderosas herramientas que
Stockbyte. Uso educativo no comercial
para plataformas públicas de Java les ofrece.
Formación Profesional a distancia.
CD-DVD Num. V43

A lo largo de nuestro aprendizaje de Java nos hemos topado en alguna ocasión con errores, pero éstos suelen ser los que nos ha
indicado el compilador. Un punto y coma que falta por aquí, un nombre de variable incorrecto por allá, pueden hacer que nuestro
compilador nos avise de estos descuidos. Cuando los vemos, se corrigen y obtenemos nuestra clase compilada correctamente.

Pero, ¿sólo existe este tipo de errores? ¿Podrían existir errores no sintácticos en nuestros programas?

Está claro que sí, un programa perfectamente compilado en el que no existen errores de sintaxis, y
que no se detectan por tanto en tiempo de compilación, puede generar otro tipo de errores que
quizá aparezcan cuando estamos usando nuestro programa, en tiempo de ejecución. A estos
errores se les conoce como excepciones, y seguramente has experimentado ya los efectos de este
tipo de errores en algún pequeño programa que, por ejemplo, reciba un número real o una cadena de
caracteres como entrada, cuando el código está esperando un número entero. Si todavía no has
experimentado esto, es un buen momento para probarlo y ver qué pasa.

Aprenderemos a gestionar de manera adecuada estas excepciones y tendremos la oportunidad de GNU Free Documentation License Erik van Leeuwen
utilizar el potente sistema de manejo de errores que Java incorpora. La potencia de este sistema de manejo de errores radica en que:

1.- El código que se encarga de manejar los errores, es perfectamente identificable en los programas. Este código puede estar
separado del código que maneja la aplicación.
2.- Java tiene una gran cantidad de errores estándar asociados a multitud de fallos comunes, como por ejemplo divisiones
por cero, fallos de entrada de datos, formato numérico erróneo, índice fuera de rango en un array o en una cadena, argumentos
no válidos en un método, y un largo etc. Al tener tantas excepciones localizadas, podemos gestionar de manera específica
cada uno de los errores que se produzcan.

En Java se pueden preparar los fragmentos de código que pueden provocar errores de ejecución para que si se produce una
excepción, el flujo del programa sea alterado, transfiriendo el control hacia ciertas zonas o rutinas que han sido creadas previamente
por el programador y cuya finalidad será el tratamiento efectivo de dichas excepciones. Estas rutinas son lanzadas (throw), y toman
el control de la situación, de forma que permiten capturar (catch) la excepción producida, y darle un tratamiento adecuado, o al
menos terminar lo más ordenadamente posible la ejecución del programa, en caso de que se tratara de un error irrecuperable. Si no
se captura la excepción, el programa se detendrá con toda probabilidad, aunque al menos podrá dar una información precisa y
detallada de qué tipo de error se ha producido, en qué línea de código, qué secuencia de instrucciones se han ejecutado hasta llegar
a esa situación. Todo ello es información útil a la hora de corregir el error.

En Java, las excepciones están representadas por clases. La clase [Link] contiene todos los tipos de excepciones.
Todas las excepciones derivarán de la clase Throwable, existiendo clases más específicas. Por debajo de la clase Throwable
existen las clases Error y Exception.

La clase Error se encargará de los errores que se produzcan en la máquina virtual, no en nuestros programas, y que por tanto,
quedan fuera del alcance de lo que nosotros podemos corregir.
La clase Exception será la que nos interese conocer, pues gestiona los errores provocados en nuestros programas.

Java lanzará una excepción en respuesta a una situación poco usual. Cuando se produce un error se genera un objeto asociado a
esa excepción. Este objeto es de la clase Exception o de alguna de sus herederas. Este objeto se pasa al código que se ha definido
para manejar la excepción. Dicho código puede manipular las propiedades del objeto Exception.

El programador también puede lanzar sus propias excepciones. Para ello se usa la cláusula throw (sin s, no confundir
con throws, con s, y que se verá en el epígrafe dedicado a delegación de excepciones). El usuario puede definir
excepciones como subclases de la clase Exception, o de alguna de alguna de sus subclases, y la cláusula throw fuerza la
generación del error invocando al método constructor de un nuevo objeto del tipo de la excepción que se quiere lanzar...
Todo ello, para ser bien entendido, requiere conocimientos de programación orientada a objetos que todavía no se han
abordado en este curso, por lo que se explicará nuevamente y ya con más detalle en próximas unidades.

Las excepciones en Java serán objetos de clases derivadas de la clase base Exception. Existe toda una jerarquía de clases derivada
de la clase base Exception, que se dividen en dos grupos principales:

Las excepciones en tiempo de ejecución, que ocurren cuando el programador no ha tenido cuidado al escribir su código.

[Link] 46/65
25/12/2018 [Link]
Las excepciones que indican que ha sucedido algo inesperado o fuera de control.

En la siguiente imagen te ofrecemos una aproximación a la jerarquía de las excepciones en Java.

[Link] 47/65
25/12/2018 [Link]

8.1.- Capturar una excepción con try.


Para poder capturar excepciones, emplearemos la estructura de captura de excepciones try-catch-
finally.

Básicamente, para capturar una excepción lo que haremos será declarar bloques de código donde
es posible que ocurra una excepción.

Esto lo haremos mediante un bloque try (intentar). Si ocurre una excepción dentro de estos bloques,
se lanza una excepción. Estas excepciones lanzadas se pueden capturar por medio de bloques
catch. Será dentro de este tipo de bloques donde se hará el manejo de las excepciones.
Beatrice Murch
Su sintaxis es:

<strong>try</strong>{
código que puede generar excepciones;
}<strong>catch</strong> (Tipo_excepcion_1 objeto_excepcion){
instrucciones para manejar excepción de Tipo_excepcion_1;
}<strong>catch</strong> (Tipo_excepcion_2 objeto_excepcion){
<code>instrucciones para manejar excepción de Tipo_excepcion_2;
}<strong>catch</strong> (...){<br /> ...<br />}<strong>finally</strong>{
instrucciones que se ejecutan siempre
}

En esta estructura, la parte catch puede repetirse tantas veces como excepciones diferentes se deseen capturar. La parte finally es
opcional y, si aparece, solo podrá hacerlo una sola vez.

Cada catch maneja un tipo de excepción. Cuando se produce una excepción, se busca el catch que posea el manejador de
excepción adecuado, será el que utilice el mismo tipo de excepción que se ha producido. Esto puede causar problemas si no se tiene
cuidado, ya que la clase Exception es la superclase de todas las demás. Por lo que si se produjo, por ejemplo, una excepción de tipo
AritmethicException y el primer catch captura el tipo genérico Exception, será ese catch el que se ejecute y no los demás.

Por eso el último catch debe ser el que capture excepciones genéricas y los primeros deben ser los más específicos. Lógicamente si
vamos a tratar a todas las excepciones (sean del tipo que sean) igual, entonces basta con un solo catch que capture objetos
Exception.

En la bibliografía sobre excepciones en Java, frecuentemente se cuestiona la utilidad de la cláusula finally, debido a que al ser
instrucciones que se ejecutan siempre, bien podrían sacarse del bloque de manejo de la excepción. Es cierto que finally no aporta la
posibilidad de hacer nada que no se pueda conseguir hacer de forma igualmente clara sin finally, por lo que en lo que a este curso
respecta, su uso queda a criterio del gusto de quien programa. Eso sí, hay que saber que existe y cómo funciona.

Debes conocer
Si deseas conocer en mayor detalle el manejo de excepciones, te aconsejamos el siguiente enlace en el que podrás
encontrar un vídeo ilustrativo sobre su creación y manejo.

Excepciones en Java.

Gestion de excepciones con try catch y throws

Resumen textual alternativo para el vídeo sobre excepciones Java

[Link] 48/65
25/12/2018 [Link]

Ejercicio Resuelto
Realiza un programa que lea por teclado un número entero empleando la clase Scanner. Utiliza la estructura try-catch
para que en caso de que se introduzca un valor no esperado, como una letra y dado que saltará una excepción, se
capturen las posibles excepciones y se informe del error. Si la lectura se hizo sin problemas, se mostrará el número
leído.

Mostrar retroalimentación

En el siguiente fichero tienes la clase que captura las excepciones con el bloque try-catch.

Captura de la entrada desde teclado a través de excepciones. (4KB)

En el ejemplo que acabamos de ver se captura cualquier excepción mediante Exception. En esta modificación
el fichero anterior, fíjate que se puede especificar según el tipo de excepción que se capture:

import [Link];
import [Link];

/**
* Clase para entender la captura de excepciones.
*
* @author JJBH
*/
public class EjemploExcepcion {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

[Link]("Escriba un número entero: ");


try {
Scanner teclado = new Scanner([Link]) ;
int numero = [Link]() ;
[Link]("El número tecleado es: " + numero);
} catch (NumberFormatException ex1) {
[Link]("Error: no es un número entero válido. ");
} catch (InputMismatchException ex2) {
[Link]("Error: formato no válido.");
}
}

Autoevaluación

Si en un programa no capturamos una excepción, será la máquina virtual de Java la que lo hará por nosotros,
pero inmediatamente detendrá la ejecución del programa y mostrará una traza y un mensaje de error.

Verdadero Falso

Verdadero
Así es, si un método no gestiona las excepciones que se producen en él, la excepción será pasada al método
que llamó al método. Y así ocurrirá sucesivamente si no existe gestión de las excepciones en niveles
superiores, hasta llegar a la máquina virtual de Java, que informará lo mejor que pueda de lo que ha ocurrido y
detendrá la ejecución del programa de la manera más ordenada posible.

[Link] 49/65
25/12/2018 [Link]

8.2.- El manejo de excepciones con catch.


¿Es obligatorio entonces el manejo de excepciones, o podemos dejar que sea la propia máquina virtual en última instancia quien las
capture y las trate?

Como hemos comentado, siempre debemos controlar las excepciones que se puedan producir o de lo contrario nuestro software
quedará expuesto a fallos. Que las excepciones las trate la propia máquina virtual, significa haber dejado que "ocurra la catástrofe", y
que el programa se termine de forma abrupta, lo que nunca es deseable.

Las excepciones pueden tratarse de dos formas:

Interrupción. En este caso se asume que el programa ha encontrado un error irrecuperable. La operación que dio lugar a la
excepción se anula y se entiende que no hay manera de regresar al código que provocó la excepción para intentar reconducir
la situación.
Reanudación. Se puede manejar el error y regresar de nuevo al código que provocó el error.

Java emplea la primera forma, pero puede simularse la segunda mediante la utilización de un bloque try en el interior de un while,
que se repetirá hasta que el error deje de existir. En la siguiente imagen tienes un ejemplo de cómo llevar a cabo esta simulación.

Ejemplo de estructura try-catch

Código de la imagen en archivo de texto para el ejemplo de uso de try-catch.


En este ejemplo, a través de la función de generación de números aleatorios (de la clase Math que incorpora Java), se obtiene el
valor del índice i. Con dicho valor se accede a una posición del array que contiene cinco cadenas de caracteres. Este acceso, a
veces puede generar un error del tipo ArrayIndexOutOfBoundsException, que debemos gestionar a través de un catch. Al estar el
bloque catch dentro de un while, se seguirá intentando el acceso hasta que no haya error, momento en que se mostrará el contenido
del array para el índice elegido, y se terminará la ejecución del ciclo.

Debes conocer
En este enlace puedes ver explicado algún ejemplo de excepciones.

Ejemplo comentado de excepciones.

Como la gestión de excepciones es un asunto bastante importante, te ponemos un enlace más con algún ejemplo
adicional.

Excepciones en Java

Ejercicio Resuelto
Realiza un programa en Java en el que se solicite al usuario la introducción de un número por teclado
comprendido entre el 0 y el 100. Si el usuario no introduce un número en dicho rango, deberá mostrarse un
mensaje de error y volver a pedir la introducción del número.

Además, utilizando el manejo de excepciones, debes controlar la entrada de dicho número y volver a solicitarlo
en caso de que ésta sea incorrecta.

Por último, muestra el número leído por pantalla, junto al número de veces que el usuario ha introducido el
número hasta darlo por bueno.

Mostrar retroalimentación

Accede al siguiente enlace, en el que podrás visualizar cómo podríamos obtener los resultados solicitados en el
enunciado del ejercicio, utilizando estructuras try-catch-finally.

Filtrado de entrada desde teclado a través de excepciones. (20KB)

En este programa se solicita repetidamente un número utilizando una estructura do-while, mientras el número
introducido sea menor que 0 y mayor que 100. Se realiza la división entera de 100 entre el número que se lea
por teclado.
Como al solicitar el número pueden producirse los errores siguientes:
[Link] 50/65
25/12/2018 [Link]
Errores de entrada al introducir una letra, o bien al introducir un número real, etc. Por ello capturaremos la
excepción InputMismatchException generada.
Errores aritméticos al intentar dividir por 0, si el usuario introduce un 0 como entrada. Por ello capturaremos
a través de la excepción <code>ArithmeticException generada.

Entonces se hace necesaria la utilización de bloques catch que gestionen cada una de las excepciones que
puedan producirse. Cuando se produce una excepción, se compara si coincide con la excepción del primer
catch. Si no coincide, se compara con la del segundo catch y así sucesivamente. Si se encuentra un catch que
coincide con la excepción a gestionar, se ejecutará el bloque de sentencias asociado a éste.
Si ningún bloque catch coincide con la excepción lanzada, dicha excepción se lanzará fuera de la estructura try-
catch-finally.
El bloque finally, se ejecutará tanto si try terminó correctamente, como si se capturó una excepción en algún
bloque catch. Por tanto, si existe bloque finally éste se ejecutará siempre.

[Link] 51/65
25/12/2018 [Link]

8.3.- Delegación de excepciones con throws.


¿Puede haber problemas con las excepciones al usar llamadas a métodos en nuestros programas?

Efectivamente, si se produjese una excepción es necesario saber quién será el encargado de


solucionarla. Puede ser que sea el propio método llamado o el código que hizo la llamada a dicho
método.

Quizá pudiéramos pensar que debería ser el propio método el que se encargue de sus excepciones,
aunque es posible hacer que la excepción sea resuelta por el código que hizo la llamada. Cuando un
método utiliza una sentencia que puede generar una excepción, pero dicha excepción no es Stockbyte.
capturada y tratada por él, sino que se encarga su gestión a quién llamó al método, decimos que se Uso educativo no comercial
para plataformas públicas de
ha delegado la excepción o que se ha producido una delegación de excepciones. Formación Profesional a distancia.
CD-DVD Num. V43

Para establecer esta delegación, en la cabecera del método se declara el tipo de excepciones que puede generar y que deberán ser
gestionadas por quien invoque a dicho método. Utilizaremos para ello la sentencia throws (con s, no confundir con throw, sin s, y que
sirve para indicar el punto del código donde se quiere lanzar una excepción). Tras la palabra throws se indica qué excepciones puede
provocar el código del método. Si ocurre una excepción en el método, el código abandona ese método y regresa al código desde el
que se llamó al método. Allí se posará en el catch apropiado para esa excepción, que la capturará y manejará adecuadamente. Si no
lo hiciera, la excepción puede seguir propagándose hasta que en el peor de los casos llegara a la máquina virtual, que la trataría
provocando que el programa aborte.

Su sintaxis es la siguiente:

public class DelegacionDeExcepciones {


...
public int leeAnio(BufferedReader lector) <strong>throws</strong> <strong>IOException, NumberFormatException</strong>{
String linea = [Link]();
Return [Link](linea);
}
...
}

Donde IOException y NumberFormatException, serían dos posibles excepciones que el método leeAnio() podría generar, pero que no
gestiona. Por tanto, un método puede incluir en su cabecera un listado de excepciones que puede lanzar, separadas por comas.

La cláusula throws avisa al compilador de que ese método puede generar errores, pero además avisa al programador de que si usa
ese método, debería capturar y manejar la excepción que puede lanzar, ya que de lo contrario el programa puede "abortar".

Debes conocer
A continuación tienes un artículo muy interesante donde se explica la gestión de excepciones con ejemplos.

Gestión de excepciones

Para saber más


Si deseas saber algo más sobre la delegación de excepciones, te proponemos el siguiente enlace:

Excepciones y delegación de éstas.

Además te volvemos a remitir al vídeo demostrativo sobre manejo de excepciones en Java que se incluyó en el
epígrafe titulado "capturar una excepción con try".

Autoevaluación
Rellena los huecos con las palabras adecuadas.

[Link] 52/65
25/12/2018 [Link]
La captura y manejo de es la forma en que Java controla los en tiempo de
.
Para ello, se definen bloques de código, mediante la palabra reservada seguida de llaves que delimitan el bloque
de código en el que se puede producir el error. Cuando la excepción se produce el control del programa se transfiere a
la primera cláusula que encuentra, para comprobar si el error es del tipo de de excepción que ahí se captura,
y si no lo es sigue comparando con las siguienes cláusulas que pueda haber. Si encuentra coincidencia con
alguna, ejecuta el bloque de código que contenga, y transfiere el control a la cláusula , si la hubiera. Esta
cláusula, de aparecer, se ejecutará siempre, tanto si se ha producido, capturado y tratado la excepción, como si no.
El usuario puede crear sus propias excepciones, además de forzar la generación de alguna excepción usando la
sentencia . También puede decidir que un método no capture ni trate una determinada excepción, sino que la
para que sea tratada por el código que hizo la llamada, avisando de ello al compilador y al programador,
con la inclusión de la cláusula seguida de los nombres de las excepciones que , separados por
comas, en la cabecera de la declaración del método.
Enviar

Si has tenido dificultades para encontrar las palabras correctas, te recomendamos que vuelvas a repasarte
todos los epígrafes anteriores, dedicados a excepciones, capturas, manejo y delegac

[Link] 53/65
25/12/2018 [Link]

9.- Recursividad.

Caso práctico
En el documento que Juan envió a María por correo electrónico, además de conceptos
sobre Programación Orientada a Objetos, había otra cosa muy interesante que le llamó
mucho la atención, y es la recursividad.

¿Pero esto qué es? ¿Se lo debería preguntar a Juan ahora, o estará durmiendo y lo
molestaré? No sé si podré aguantar hasta mañana,... -piensa María.

Adolfo Llopis Ibañez

¿Has oído alguna vez la máxima de que en la definición no debe usarse lo que se intenta definir?
Parece lógico que si me piden definir lo que es un ordenador, decir que es una especie de
ordenador que permite…, no aporta mucha información, no es la mejor manera de empezar la
definición.

Aunque esa máxima es muy lógica y sensata a la hora de hablar en nuestra vida diaria, ya puedes ir
olvidándola en el caso de la programación, al igual que en matemáticas, donde existen definiciones
por recurrencia:

Se define alguna propiedad para el primer número Natural, cero.


Suponiendo que la propiedad está definida para un número Natural cualquiera, llamado n,
usamos esa definición para definirla también para el siguiente número Natural, n+1
De esta forma queda definida para todo el conjunto de los números Naturales. Gabriel Esteffan

En programación, usamos el término recursividad para referirnos a procedimientos o métodos que contienen en su
implementación llamadas a sí mismo, es decir un método es recursivo si para ejecutarse se llama a sí mismo.

El aspecto de la declaración de un método recursivo es algo como lo que sigue:

metodoRecursivo(){

sentencia;

sentencia;

metodoRecursivo();

sentencia;

sentencia;

Hemos resaltado en negrita la llamada que el método se hace a sí mismo.

Pero, si para ejecutar a un método hay que hacer una llamada al mismo método que a su vez hará una llamada al mismo método, y
así sucesivamente, ¿no habremos entrado en un bucle infinito que hará que nunca terminemos?

No, si las cosas se hacen bien. Aunque evidentemente, es posible hacerlas mal. ¿Qué debemos tener en cuenta a la hora de saber
si un método recursivo está bien definido?

Además de la llamada al propio método, deben existir otras sentencias en la definición del método que establezcan al
menos un caso base, es decir, un caso para el que se conoce la solución, y para el que la llamada al método puede devolver
un valor o terminar la ejecución sin necesidad de volver a invocar de nuevo al propio método.
Cada nueva llamada al propio método debe reducir el problema, es decir, debe acercarnos más al caso base.
La solución debe ser correcta para los casos no base. Es decir, debemos ser capaces de expresar correctamente la
solución de un caso a partir de la soluciones de casos menos complejos, para poder construir la solución de cualquier caso a
partir de las soluciones del caso base.

[Link] 54/65
25/12/2018 [Link]

Citas Para Pensar


Para entender lo que es la Recursividad, antes hay que entender lo que es la Recursividad.

Anónimo.

[Link] 55/65
25/12/2018 [Link]

9.1.- Concepto de Recursividad.


El concepto suele entenderse mejor con el ejemplo del cálculo del factorial de un número. El factorial
de un número entero positivo n se representa como n! (que se lee como “n factorial”)

Sabemos que dado un número entero positivo, el factorial se puede definir de dos formas:

Definición Iterativa. Como el producto de todos los números enteros comprendidos entre 1 y el
propio número:

n != n*(n-1)*(n-2)*…*3*2*1. Además, por convenio, para extender la definición también al cero, Blanca Egea

se define: 0! = 1

Para calcular el factorial de esta forma, tenemos que repetir un ciclo en el que se vaya acumulando el producto del número por el
anterior, hasta que lleguemos a uno.

Definición Recursiva. Como el producto del propio número por el factorial del número anterior.

Es evidente que (n-1)! = (n-1)* (n-2)*…*3*2*1, lo que nos lleva a poder escribir que n! = n * (n-1)!, siendo además 0! = 1 igual
que antes. Acabamos de hacer una definición por recurrencia del factorial de un número. “El factorial de un número vale 1 si el
número es cero, y el producto del propio número por el factorial del anterior, en otro caso.”

Para calcular el factorial de esta forma, es como si le encargáramos la tarea a una persona, que no sabe calcular el valor final del
factorial de n, pero sabe que es n * (n-1)!, y le pregunta a otra persona el valor de (n-1)! Esta persona, tampoco sabe calcular el
valor final de (n-1)!, pero sabe que es (n-1)*(n-2)!, y le pregunta a su vez a otra persona el valor de (n-2)!, y así sucesivamente
hasta que llegamos a preguntarle a una persona el valor de 0! Y esa persona responde que 0! =1. A partir de ese momento, la
persona que le preguntó tiene toda la información para calcular 1!, lo calcula, y le responde a la persona que le preguntó, que
completa el cálculo de 2!, y así sucesivamente, hasta llegar a la persona que calcula (n-1)!, que completa el cálculo y le
proporciona su valor a quien le preguntó, que multiplica ese valor por n y obtiene el valor de n!.

Para saber más


Puedes consultar esta web para entender mejor la presentación sobre el factorial, que tienes más abajo.

Información sobre la el concepto de Pila

Cálculo de factorial recursivamente.


Resumen de la presentación.

Presentación a pantalla completa,

Al igual que tenemos dos definiciones del factorial, una iterativa y otra recursiva, un problema lo podemos resolver mediante un
método que sea iterativo, ajustándose a la primera definición o mediante un método recursivo, que se ajuste a la segunda. La
solución recursiva, en este caso, es más elegante, en el sentido de que genera un código más breve, y más simple de entender,
es muy intuitiva.

La recursividad es una poderosa herramienta en programación y ofrece una alternativa a las soluciones iterativas complejas de
algunos algoritmos.

¿Cuáles son entonces las razones para usar la recursividad?

Los problemas resultan más fáciles de resolver que con estructuras iterativas.
Proporciona soluciones más simples.
Proporciona soluciones elegantes.

Autoevaluación
¿Qué debemos tener en cuenta a la hora de saber si un método recursivo está bien definido? Señala la afirmación
correcta.

Debemos ser capaces de expresar correctamente la solución de un caso a partir de la soluciones de casos
menos complejos, para poder construir la solución de cualquier caso a partir de las soluciones del caso base.

[Link] 56/65
25/12/2018 [Link]
Debemos ser capaces de expresar correctamente la solución de un caso a partir de la soluciones de casos más
complejos

La solución puede no ser correcta para los casos no base.

Todas las anteriores son correctas.

¡Exacto! Esa es la cuestión.

No, no es eso.

No, inténtalo de nuevo.

No, no es correcto.

Solución

1. Opción correcta
2. Incorrecto
3. Incorrecto
4. Incorrecto

[Link] 57/65
25/12/2018 [Link]

9.2.- Recursión frente a iteración.


En el caso del factorial hemos visto que había dos posibles soluciones, una iterativa y otra recursiva.

¿Siempre va a existir una solución iterativa o hay casos en los que obligatoriamente tendremos que
usar recursividad?

No sólo no existen casos en los que sea obligatoria, sino que siempre existe una solución
iterativa, y ésta siempre será más eficiente, es decir, necesitará consumir menos recursos de
memoria y de CPU, y obtendrá la solución en menos tiempo.

Lo que ocurre es que a veces, por la naturaleza recursiva del problema, no es fácil encontrar la rob van de Pavert
solución iterativa, o resulta complicada y difícil de entender.

La recursividad se debe usar cuando sea realmente necesaria, es decir, cuando no exista una solución iterativa simple.
Cuando las dos soluciones son fácilmente expresables, siempre será preferible la solución iterativa.

Por otro lado, la recursividad requiere hacer una asignación dinámica de memoria, que no es posible en todos los lenguajes de
programación. (Sí lo es en Java y en otros muchos).

Cada vez que se hace una nueva llamada al método recursivo, es necesario guardar en la pila (stack) todos los datos de la
llamada anterior que aún no ha terminado (todas las variables de memoria que tenga definidas el método), lo que se conoce como
entorno volátil de esa ejecución.

Esto incluye almacenar en la memoria todos los valores de los registros del microprocesador, para poder restablecerlos
posteriormente y continuar por el mismo punto de la ejecución de esa llamada que lo habíamos dejado.

Como puede haber muchas llamadas sucesivas, éstas se van almacenando en la pila, de forma que se irán retirando de ella en el
orden contrario a como se introdujeron. Así, el último en entrar es el primero en salir. (Estructura LIFO). De este modo, el
procesador de la computadora tiene que dedicarse a:

guardar los datos de cada ejecución en la pila,


cargar los de la nueva llamada para cuando al final ésta termine,
ir de nuevo sacando esos valores de la pila en orden contrario a como se introdujeron,
para restaurarlos en la CPU y completar la llamada.

Esa es la causa responsable de que las soluciones recursivas requieran mucho más tiempo de CPU y mucha más memoria.

Con una solución iterativa sólo tendremos un método ejecutándose, por lo que sólo necesitaremos memoria para una copia de cada
una de las variables que usa ese método. Por otro lado, no hay que hacer ninguna operación de almacenar en la pila los datos de la
ejecución para posteriormente reanudarla, ya que la llamada al método iterativo se ejecuta hasta finalizar, sin tener que
intercambiarse con ninguna otra llamada.

En este sentido, el factorial no es el mejor ejemplo que se puede mostrar de uso adecuado de una solución recursiva, ya que existe
una solución iterativa igualmente clara y simple, que siempre va a ser más eficiente.

Autoevaluación
Señala la afirmación correcta. Respecto a la recursividad frente a la iteración, podemos afirmar que:

Si existe una solución recursiva a un problema, no siempre existe una solución iterativa.

A veces, por la naturaleza recursiva del problema, no es fácil encontrar la solución iterativa, o resulta complicada
y difícil de entender.

La solución recursiva necesitará consumir menos recursos de memoria y de CPU, y obtendrá la solución en
menos tiempo.

Todas las respuestas anteriores son correctas.

Incorrecto

¡Muy bien!

Incorrecta.

No es así, hay sólo una correcta.

[Link] 58/65
25/12/2018 [Link]

Solución

1. Incorrecto
2. Opción correcta
3. Incorrecto
4. Incorrecto

[Link] 59/65
25/12/2018 [Link]

9.3.- Ejemplos de uso.


¿Verdad que algún ejemplo de programa recursivo ayudaría a entender mejor estos conceptos?

Hemos venido contando las características a tener en cuenta sobre la recursividad, su definición, y
algunas consideraciones generales sobre su uso.

Con los ejemplos de los apartados siguientes, pretendemos dar una idea de la recursividad. Son
ejemplos que ayudan por su sencillez y claridad a comprender el concepto de recursividad, pero que
presentan una solución iterativa simple que es igualmente clara y más eficiente (factorial,
Fibonacci y máximo común divisor)
Lee Coursey
No ahondaremos en problemas más complicados, pero que sepas que hay ejemplos que escapan a
las pretensiones del módulo, en los que, a pesar de que existe la solución iterativa, ésta es difícil de imaginar, y la recursividad aporta
una solución simple y elegante. Estos casos son por ejemplo: el problema de las Torres de Hanoi, Ordenación por QuickSort, etc.

También se usa la recursividad en un un tipo especial de problemas, denominados algoritmos de Vuelta atrás o Backtracking, que
consisten en explorar de forma sistemática todos los caminos posibles para alcanzar la solución, y si algún camino nos lleva a un
punto en el que no es posible alcanzar la solución deseada, se vuelve atrás hasta alcanzar un punto en el que es posible continuar
explorando nuevas alternativas. Es el caso de problemas para encontrar la salida de un laberinto, o para calcular los movimientos de
una ficha en el tablero de ajedrez.

Para saber más


En esta web puedes probar el juego de las torres de Hanoi:

Torres de Hanoi.

[Link] 60/65
25/12/2018 [Link]

9.3.1.- Factorial.
Éste es el primer ejemplo de recursividad que vamos a ver. ¿Por qué lo elegimos como el
primero?

Porque es el más simple de todos, y el que más ayuda a aclarar los conceptos.

Presentaremos tanto una solución iterativa, como una solución recursiva.

Primero te recomendamos que veas el código de la versión iterativa. Como puedes observar, esta
solución es totalmente clara, y al ser más eficiente, será preferible a la solución recursiva.

Ejercicio resuelto factorial iterativamente (2 KB)

A continuación aparece el enlace a la versión recursiva. Como ves, es una solución elegante, que
ayuda a comprender el concepto de recursividad, pero que no aporta claridad ni sencillez, por lo que al ser menos eficiente que la
solución iterativa, no sería adecuado usar recursividad en este caso.

Ejercicio resuelto factorial recursivamente (3 KB)

Autoevaluación
¿Cuáles es la razón fundamental para usar la recursividad? Señala la afirmación correcta.

Los problemas resultan más fáciles de resolver que con estructuras iterativas.

Proporciona soluciones más simples.

Proporciona soluciones elegantes.

Todas las anteriores son correctas.

No, hay más.

No, existen más razones.

Incorrecto.

¡Muy bien! Esa es la respuesta correcta.

Solución

1. Incorrecto
2. Incorrecto
3. Incorrecto
4. Opción correcta

[Link] 61/65
25/12/2018 [Link]

9.3.2.- Serie de Fibonacci.


¿Empiezas a ver claras las diferencias entre un buen uso de la recursividad y un mal uso? El
ejemplo de la sucesión de Fibonacci pone de manifiesto más aún, esas diferencias.

Al igual que en el caso del factorial, existe una solución iterativa que es bastante sencilla y
clara, por lo que la recursividad lo único que aporta es un mayor parecido con la definición de la
función. Pero en este caso, tenemos el agravante de que cada llamada a la función genera dos
nuevas llamadas recursivas, con lo que la eficiencia decrece considerablemente. Se produce
una explosión exponencial del número de llamadas recursivas, repitiéndose además cálculos
de forma innecesaria. Así, resulta aún más desaconsejable el uso de la recursividad en este
caso.

La función Fibonacci calcula el valor del término n-ésimo de la sucesión de Fibonacci, en la que
el primer término es 0, el segundo 1 y a partir de ahí, cada nuevo término se calcula como la east_mountain

suma de los dos inmediatamente anteriores. Puede también inicializarse los dos primeros términos con otros valores, pero lo que no
cambia es la forma de obtener los sucesivos términos.

Por tanto, la función Fibonacci se puede definir como:

fib(n) = n, si n = 0 ó n = 1
fib(n) = fib(n-1) + fib(n-2), si n >1

Esta definición de la función es muy clara e intuitiva, y el algoritmo recursivo que la implementa es muy sencillo de hacer, pero muy
ineficiente. Si intentas calcular el término 40 de la sucesión, verás cómo tarda un tiempo considerable en resolverlo, y si introduces
un valor más alto, posiblemente tendrás la sensación de que el ordenador se ha bloqueado, debido a lo que tarda. Ese tiempo, no
obstante, será mayor o menor dependiendo de la potencia de tu ordenador.

Ejercicio resuelto fibonacci recursiva (2 KB)

Fibonacci

Not Found
The requested URL
/cursos/blocks/recopila/PROG04_CONT_R65_Fibonacci.[Link]
was not found on this server.

Resumen de la presentación.

Presentación a pantalla completa.

A continuación presentamos el código de la solución iterativa, que también es claro y fácil de programar, aunque quizás no tan
elegante, pero desde luego es mucho más eficiente. Al ejecutarlo comprueba el tiempo que tarda en ejecutarse para el caso de que
el número sea 100. Prácticamente es instantáneo. Sin embargo, la solución recursiva, ya tardaba mucho más de lo razonable para
números mayores de 40. Claramente, la solución iterativa es mucho más eficiente.

Ejercicio resuelto fibonacci iterativa (2 KB)

Para saber más


Puedes consultar un resumen de la biografía de Fibonacci en este enlace:

Cursiosidades sobre Fibonacci.

[Link] 62/65
25/12/2018 [Link]

9.3.3.- Máximo común divisor.


¿Necesitas algún ejemplo más para aclararte las ideas?

Éste es otro caso en el que la solución iterativa sería más eficiente, y por tanto preferible: el
cálculo del máximo común divisor de dos números por el algoritmo de Euclides. No aporta
por tanto ninguna novedad, salvo la de comprobar que casi cualquier algoritmo iterativo puede
tener una versión recursiva, y mostrar un ejemplo más de problema recursivo.

El cálculo del máximo común divisor de dos números enteros por el algoritmo de Euclides,
consiste en:

Dividir el mayor entre el menor.


Repetir los pasos siguientes hasta que obtengamos un resto cero.
Si el resto de la división es 0, el máximo común divisor es el divisor.
En caso contrario, seguiremos dividiendo, tomando como dividendo el divisor, y como divisor el resto de la división
anterior.

Por tanto, el máximo común divisor será el último resto no nulo de esas divisiones sucesivas, que también es el divisor de la última
división para la que se ha obtenido resto 0.

Ejercicio resuelto Máximo común divisor (2 KB)

Para saber más


Con este juego de un libro de educación primaria, puedes comprobar el máximo común divisor de muchos números de
manera divertida.

Máximo común divisor

[Link] 63/65
25/12/2018 [Link]

Condiciones y términos de uso de los materiales

Materiales desarrollados inicialmente por el Ministerio de Educación, Cultura y Deporte y actualizados por el
profesorado de la Junta de Andalucía bajo licencia Creative Commons BY-NC-SA.

Antes de cualquier uso leer detenidamente el siguente Aviso legal

Historial de actualizaciones

Versión: 01.03.02 Fecha de actualización: 23/10/18

Actualización de materiales y correcciones menores.

Versión: 01.03.00 Fecha de actualización: 11/10/18 Autoría: José Javier Bermúdez Hernández

Ubicación: Apartados 6.4, 7.2 y 8.1


Mejora (tipo 1): Pasar http a https en los vídeos de dichos apartados 6.4, 7.2 y 8.1
Ubicación: 6.1.
Mejora (tipo 1): Pasar http a https en los vídeos del Para saber más
Ubicación: Sección 8
Mejora (tipo 2): Se añade el apartado 8 de expceciones, que anteriormente estaba en el tema 2.
Ubicación: Actualizado el mapa al incorporar a la unidad el apartdo 8 de excepciones
Mejora (Mapa conceptual): Actualizado el mapa al incorporar a la unidad el apartdo 8 de excepciones
Ubicación: Indice
Mejora (Orientaciones del alumnado): Se ha actualizado el índice por la incorporación del apartado 8 de excepciones.

Versión: 01.02.00 Fecha de actualización: 14/11/14 Autoría: José Javier Bermúdez Hernández

Se ha añadido el apartado final de Recursividad, que aunque no viene en normativa, se estima importante para la formación del
alumnado. Además, se han incorporado las sugerencias del curso pasado y algunas imágenes del anexo se han eliminado del
mismo, para incorporar las credenciales en el pie de cada foto.

Versión: 01.01.00 Fecha de actualización: 19/11/13 Autoría: José Javier Bermúdez Hernández

Se ha completado la accesibilidad donde hacía falta, se han renombrado y vuelto a enlazar los recursos para que el nombre
indique correctamente la unidad (aunque no se han enlazado con créditos a pie de foto). Se han modificado los enlaces al
glosario por definiciones dentro del propio eXe. Se han modificado los ejemplos de código para que hagan uso de la
nomenclatura correcta para identificadores de clases, métodos y variables, revisando que en las capturas de pantalla también se
corrigieran l

Versión: 01.00.00 Fecha de actualización: 19/11/13

Versión inicial de los materiales.

[Link] 64/65
25/12/2018 [Link]

[Link] 65/65

También podría gustarte