Apuntes_POO_Unidad_1_v0.3

72
Programación Orientada a Objetos 1 Apuntes Programación Orientada a Objetos con JAVA UNIDAD 1 Parte del material, ejemplos y ejercicios ha sido tomado de los siguientes textos: - Java Cómo Programar, 5ta Edición. Deitel. Pearson Prentice Hall. ISBN: 970-26-0518-0 - Learning Java, 3rd Edition. Jonathan Knudsen, Patrick Niemeyer. O’Reilly. ISBN: 0-596-00873-2 - Java, Java, Java™: Object-Oriented Problem Solving, Third Edition. Ralph Morelli, Ralph Walde - Trinity College. Prentice Hall, 2005. ISBN: 978-0-13-147434-5 - Java™ Puzzlers: Traps, Pitfalls, and Corner Cases. Joshua Bloch, Neal Gafter. Addison Wesley Professional, 2005. ISBN: 0-321-33678-X

Transcript of Apuntes_POO_Unidad_1_v0.3

Page 1: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

1

Apuntes

Programación Orientada a Objetos con JAVA

UNIDAD 1

Parte del material, ejemplos y ejercicios ha sido tomado de los siguientes textos:

- Java Cómo Programar, 5ta Edición. Deitel. Pearson Prentice Hall. ISBN: 970-26-0518-0

- Learning Java, 3rd Edition. Jonathan Knudsen, Patrick Niemeyer. O’Reilly. ISBN: 0-596-00873-2

- Java, Java, Java™: Object-Oriented Problem Solving, Third Edition. Ralph Morelli, Ralph Walde - Trinity College. Prentice Hall, 2005. ISBN: 978-0-13-147434-5

- Java™ Puzzlers: Traps, Pitfalls, and Corner Cases. Joshua Bloch, Neal Gafter. Addison Wesley Professional, 2005. ISBN: 0-321-33678-X

Page 2: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

2

Tabla de Contenidos

CAPÍTULO 1 PRELIMINARES ................................................................................................4

1.1 Concepto de algoritmo y programa computacional........................................................................................................4

1.2 Lenguajes de programación..............................................................................................................................................4

1.3 JAVA: multiplataforma ....................................................................................................................................................7

1.4 JAVA: compilado o interpretado .....................................................................................................................................8

1.5 ¿Por qué JAVA? ................................................................................................................................................................9

1.6 Historia de JAVA.............................................................................................................................................................10

1.7 Paradigma Orientado a Objetos.....................................................................................................................................12 1.7.1 Introducción ...............................................................................................................................................................13 1.7.2 Origen ........................................................................................................................................................................13 1.7.3 Diferencias con la programación estructurada ...........................................................................................................14 1.7.4 La Programación Orientada a Objetos (POO) como solución ...................................................................................15 1.7.5 Características de la POO ..........................................................................................................................................16

CAPÍTULO 2 PRIMEROS PROGRAMAS Y ASPECTOS BÁSICOS ....................................17

2.1 Primer programa.............................................................................................................................................................17 2.1.1 Comentarios ...............................................................................................................................................................17 2.1.2 Salida de información con el objeto System.out ........................................................................................................17 2.1.3 Errores comunes.........................................................................................................................................................18 2.1.4 Algunas modificaciones.............................................................................................................................................18

2.2 Uso de Objetos y Clases...................................................................................................................................................19

2.3 Flujos de Entrada: ingresar datos al programa desde teclado ....................................................................................20

2.4 Variables y Tipos de datos primitivos............................................................................................................................21 2.4.1 Declaración y uso de variables...................................................................................................................................22 2.4.2 Tipo de datos String ...................................................................................................................................................22

2.5 Operaciones......................................................................................................................................................................23 2.5.1 Precedencia de operadores .........................................................................................................................................25 2.5.2 Overflow ....................................................................................................................................................................25

2.6 Conversión básica entre tipos de datos distintos...........................................................................................................26 2.6.1 Conversión automática...............................................................................................................................................26 2.6.2 Clases Asociadas con Tipos Primitivos .....................................................................................................................26

2.7 Estructura de control condicional (if - else)...................................................................................................................27 2.7.1 Cuidar la indentación .................................................................................................................................................28

2.8 Ejemplos desarrollados ...................................................................................................................................................30 2.8.1 Numero par ................................................................................................................................................................30 2.8.2 Factor .........................................................................................................................................................................31 2.8.3 Conversor de Temperatura.........................................................................................................................................32

Page 3: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

3

2.9 Ejercicios ..........................................................................................................................................................................33

CAPÍTULO 3 CONTROL DEL PROGRAMA .........................................................................35

3.1 Estructura de Control Secuencial...................................................................................................................................36

3.2 Estructuras de Control de Selección ..............................................................................................................................36

3.3 Estructuras de control cíclicas........................................................................................................................................37 3.3.1 Repeticiones controladas por contador ......................................................................................................................38 3.3.2 Repeticiones controladas por centinela ......................................................................................................................40

3.4 Ejemplos desarrollados I.................................................................................................................................................42 3.4.1 Factorial .....................................................................................................................................................................42 3.4.2 Pedir un valor de entrada hasta que sea válido...........................................................................................................43 3.4.3 Cálculo de la raiz cuadrada por aproximación ...........................................................................................................44 3.4.4 Comprobar si un número es primo.............................................................................................................................44

3.5 Estructura de Selección Múltiple ...................................................................................................................................46

3.6 Instrucciones break y continue ................................................................................................................................50

3.7 Ejercicios ..........................................................................................................................................................................51

CAPÍTULO 4 PROGRAMAS MODULARES CON MÉTODOS..............................................52

4.1 Módulos ............................................................................................................................................................................52

4.2 Módulos en JAVA: clases y métodos..............................................................................................................................53

4.3 Estructura de un método.................................................................................................................................................54

4.4 Ejemplos desarrollados ...................................................................................................................................................56 4.4.1 Conversor decimal a binario ......................................................................................................................................56 4.4.2 Suma de binarios........................................................................................................................................................57 4.4.3 Palíndromo.................................................................................................................................................................59

4.5 Bibliotecas de funciones ..................................................................................................................................................60

4.6 Ejercicios ..........................................................................................................................................................................62

CAPÍTULO 5 ARREGLOS [PARTE 1]...................................................................................63

5.1 Crear arreglos ..................................................................................................................................................................63

5.2 Acceder a los elementos de un arreglo ...........................................................................................................................64

5.3 Recorrer un arreglo.........................................................................................................................................................64

5.4 Programas de ejemplo.....................................................................................................................................................65

5.5 Arreglos y métodos ..........................................................................................................................................................66 5.5.1 Arreglos como parámetros de entrada........................................................................................................................66 5.5.2 Arreglos como salida de un método...........................................................................................................................67

5.6 Ejemplos desarrollados ...................................................................................................................................................69

5.7 Ejercicios ..........................................................................................................................................................................72

Page 4: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

4

Capítulo 1 Preliminares

1.1 Concepto de algoritmo y programa computacional

Un algoritmo (del árabe al-Jwarizmi, matemático del siglo IX) es un conjunto finito de instrucciones o pasos que sirven para ejecutar una tarea o resolver un problema.

El término algoritmo no está exclusivamente relacionado con la matemática, ciencias de la computación o informática. En realidad, en la vida cotidiana empleamos algoritmos en multitud de ocasiones para resolver diversos problemas. Algunos ejemplos son el uso de una lavadora (se siguen las instrucciones), pero no la preparación de una comida (porque no están perfectamente definidos los pasos) o el mismo lenguaje humano que "transforma" nuestros pensamientos en sonidos y hace que otro humano nos pueda entender. También existen ejemplos de índole matemática, como el algoritmo de la división para calcular el cociente de dos números, el algoritmo de Euclides para calcular el máximo común divisor de dos enteros positivos, o incluso el método de Gauss para resolver Sistema lineal de ecuaciones.

Wikipedia

http://es.wikipedia.org/wiki/Algoritmo

Un programa computacional es uno o más algoritmos escritos en un lenguaje que una máquina (un computador) puede "entender" y llevar a cabo.

Una característica general de los programas computacionales es que su objetivo es siempre el procesamiento de información. Por lo general, un programa tiene flujos de información de entrada y flujos de información de salida (I/O : Input/Output). La información o datos puede entrar y salir del programa de y hacia diversos medios y dispositivos: almacenamiento físico (discos), almacenamiento lógico (memoria RAM), teclado, mouse, pantalla, impresora, scanner, micrófono, tarjetas capturadoras, red, modem, etc.

datos datosprocesamientodatos datosprocesamiento

1.2 Lenguajes de programación

Para que una máquina entienda un programa, éste debe estar escrito en su propio lenguaje. El lenguaje que una máquina entiende son las secuencias binarias que identifican las instrucciones básicas: sumar, incrementar, multiplicar, etc.

Sin embargo, los lenguajes de máquina no son fácilmente entendibles para nosotros. Por ejemplo, la simple expresión (a + b) vista de manera binaria, donde

Page 5: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

5

podría ser una expresión en lenguaje de máquina como

Resulta natural pensar en la necesidad de lenguajes que permitan trabajar con estas instrucciones de manera más natural, es decir un lenguaje más cercano al lenguaje humano.

Con respecto al qué tan cercano es un lenguaje de programación al lenguaje de máquina existen:

Lenguajes de bajo nivel

Los lenguajes de bajo nivel son lenguajes de programación que se acercan al funcionamiento de una computadora. El lenguaje de más bajo nivel es, por excelencia, el código máquina. A éste le sigue el lenguaje ensamblador, ya que al programar en ensamblador se trabajan con los registros de memoria de la computadora de forma directa.

Lenguajes de medio nivel

Hay lenguajes de programación que son considerados por algunos expertos como lenguajes de medio nivel (como es el caso del lenguaje C) al tener ciertas características que los acercan a los lenguajes de bajo nivel pero teniendo, al mismo tiempo, ciertas cualidades que lo hacen un lenguaje más cercano al humano y, por tanto, de alto nivel.

Lenguajes de alto nivel

Los lenguajes de alto nivel son normalmente fáciles de aprender porque están formados por elementos de lenguajes naturales, como el inglés. En BASIC, el lenguaje de alto nivel más conocido, los comandos como "IF CONTADOR = 10 THEN STOP" pueden utilizarse para pedir a la computadora que pare si CONTADOR es igual a 10. Por desgracia para muchas personas esta forma de trabajar es un poco frustrante, dado que a pesar de que las computadoras parecen comprender un lenguaje natural, lo hacen en realidad de una forma rígida y sistemática.

Wikipedia

http://es.wikipedia.org/wiki/Lenguaje_de_programacion

Cualquier programa escrito en un lenguaje distinto al lenguaje de máquina debe traducirse a éste. Este proceso es realizado por otro programa llamado traductor.

Page 6: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

6

El código fuente (source code), nuestro programa escrito en un lenguaje de alto nivel, es traducido a código objeto (object code), que es como se denomina al programa en código de máquina.

De acuerdo al proceso de traducción, los lenguajes de programación pueden clasificarse en dos tipos:

Lenguajes compilados

Naturalmente, un programa que se escribe en un lenguaje de alto nivel también tiene que traducirse a un código que pueda utilizar la máquina. Los programas traductores que pueden realizar esta operación se llaman compiladores. Éstos, como los programas ensambladores avanzados, pueden generar muchas líneas de código de máquina por cada proposición del programa fuente. Se requiere una corrida de compilación antes de procesar los datos de un problema.

Los compiladores son aquellos cuya función es traducir un programa escrito en un determinado lenguaje a un idioma que la computadora entienda (lenguaje máquina con código binario).

Al usar un lenguaje compilado (como lo son los lenguajes del popular Visual Studio de Microsoft), el programa desarrollado nunca se ejecuta mientras haya errores, sino hasta que luego de haber compilado el programa, ya no aparecen errores en el código.

Lenguajes interpretados

Se puede también utilizar una alternativa diferente de los compiladores para traducir lenguajes de alto nivel. En vez de traducir el programa fuente y grabar en forma permanente el código objeto que se produce durante la corrida de compilación para utilizarlo en una corrida de producción futura, el programador sólo carga el programa fuente en la computadora junto con los datos que se van a procesar. A continuación, un programa intérprete, almacenado en el sistema operativo del disco, o incluido de manera permanente

Page 7: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

7

dentro de la máquina, convierte cada proposición del programa fuente en lenguaje de máquina conforme vaya siendo necesario durante el proceso de los datos. No se graba el código objeto para utilizarlo posteriormente.

La siguiente vez que se utilice una instrucción, se le debe interpretar otra vez y traducir a lenguaje máquina. Por ejemplo, durante el procesamiento repetitivo de los pasos de un ciclo, cada instrucción del ciclo tendrá que volver a ser interpretado cada vez que se ejecute el ciclo, lo cual hace que el programa sea más lento en tiempo de ejecución (porque se va revisando el código en tiempo de ejecución) pero más rápido en tiempo de diseño (porque no se tiene que estar compilando a cada momento el código completo). El intérprete elimina la necesidad de realizar una corrida de compilación después de cada modificación del programa cuando se quiere agregar funciones o corregir errores; pero es obvio que un programa objeto compilado con antelación deberá ejecutarse con mucha mayor rapidez que uno que se debe interpretar a cada paso durante una corrida de producción.

Wikipedia

http://es.wikipedia.org/wiki/Lenguaje_de_programacion

Existen por lo tanto, traductores de tipo compilador, y traductores de tipo intérprete.

Ejemplos de lenguajes compilados e interpretados:

– Lenguajes compilados: – Fortran – Pascal – C – C++ – Java

– Lenguajes interpretados – JavaScript – PHP – Python – Java

1.3 JAVA: multiplataforma

Una consideración importante en la programación es la variedad que existe de lenguajes de máquina. En rigor, cada arquitectura de computador entiende un lenguaje de máquina distinto, es decir, posee un conjunto o set de instrucciones distintas. Entonces, cuando compilamos un programa, el código objeto (el programa compilado) sólo servirá en la máquina para la cual compilamos. Así por ejemplo, si escribimos un programa en C y lo compilamos para máquina Intel con set de instrucciones CISC, no podremos ejecutarlo en una máquina PowerPC RISC sin antes compilarlo nuevamente. Este problema se agrava debido a que la compilación

Page 8: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

8

no sólo es sensible a la máquina física, si no que también al ambiente de software que define el sistema operativo. A la combinación entre arquitectura física y sistema operativo se denomina Plataforma.

En la práctica, no sólo es necesario compilar un programa con tantos compiladores como plataforma queremos que soporte, si no también, lo más seguro es que parte del código fuente deba ser modificado. Este problema no es trivial, y dificulta y encarece el desarrollo de software.

S.O. Windows

Arquitectura Intel

S.O. Unix

Arquitectura Intel

S.O. Linux

Arquitectura Mac (RISC)

S.O. Unix

Arquitectura SPARC

MAC OSX

Arquitectura PowerPC/RISC

S.O. Windows

Arquitectura Intel

S.O. Unix

Arquitectura Intel

S.O. Linux

Arquitectura Mac (RISC)

S.O. Unix

Arquitectura SPARC

MAC OSX

Arquitectura PowerPC/RISC

JAVA soluciona el problema haciéndose multiplataforma. La clave es poner una capa intermedia, la máquina virtual, que sí es dependiente de la plataforma y que actúa como otra plataforma. De esta manera, un programa JAVA se ejecuta siempre sobre la misma máquina virtual o plataforma JAVA.

Es evidente que existirán tantas versiones de la máquina virtual como plataformas de hardware-software existan.

1.4 JAVA: compilado o interpretado

Existe una discusión en torno a la pregunta ¿es JAVA un lenguaje compilado o interpretado? La pregunta surje del hecho de que el código fuente JAVA es compilado para obtener un código objeto denominado bytecode y éste a su vez es interpretado por la máquina virtual JAVA para generar el código de máquina.

Page 9: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

9

1.5 ¿Por qué JAVA?

Las características de JAVA, según sus propios creadores (������������� ��) son:

"Un lenguaje simple. Orientado al objeto, distribuido, interpretado, sólido, seguro, de arquitectura neutral, portable, de lato desempeño, de multihilos y dinámico"

1. Simple

Basado en el lenguaje C++ pero donde se eliminan muchas de las características OOP que se utilizan esporádicamente y que creaban frecuentes problemas a los programadores. Esta eliminación de causas de error y problemas de mantenimiento facilita y reduce el coste del desarrollo de software.

• Java no da soporte a struct, union y pointer

• Java no ofrece typedef ni #define

• No permite la sobrecarga de operadores.

• No ofrece herencia múltiple.

• Maneja los comandos en línea de diferente manera que C++

• Java tienen una clase String, que permite un mejor manejo que los arrays de terminación nula del C y C++.

• Java tiene un sistema automático de asignación y liberación de memoria (recolector de basura) que mejora mucho los sistemas del C++

2. Orientado al objeto

Java da buen soporte a las técnicas de desarrollo OOP y en resumen a la reutilización de componentes de software.

3. Distribuido

Java se ha diseñado para trabajar en ambiente de redes y contienen una gran biblioteca de clases para la utilización del protocolo TCP/IP, incluyendo HTTP y FTP. El código Java se puede manipular a través de recursos URL con la misma facilidad que C y C++ utilizan recursos locales (archivos).

4. Interpretado

El compilador Java traduce cada fichero fuente de clases a código de bytes (Bytecode), que puede ser interpretado por todas las máquinas que den soporte a un visualizador de que funcione con Java. Este Bytecode no es especifico de una máquina determinada, por lo que no se compila y enlaza como en el ciclo clásico, sino que se interpreta.

5. Sólido

El código Java no se quiebra fácilmente ante errores de programación. Así el relaje que existe en la declaración y manejo de tipos en C y C++ se torna en restricciones en Java, donde no es posible la conversión forzada (cast) de enteros en punteros y no ofrece soporte a los punteros que permitan saltarse reglas de manejo de tipos. Así en Java no es posible escribir en áreas arbitrarias

Page 10: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

10

de memoria ni realizar operaciones que corrompan el código. En resumen se eliminan muchas de las posibilidades de "trucos" que ofrecía el C y C++.

6. Seguro

Como Java suele funcionar en ambiente de redes el tema de seguridad debe interesar en sobremanera. Las mismas características antes descritas que evitan la corrupción de código evitan su manipulación. Actualmente se esta trabajando en encriptar el código.

7. Arquitectura neutral

El compilador crea códigos de byte (Bytecode) que se envía al visualizador solicitado y se interpreta en la máquina que posee un interprete de Java o dispone de un visualizador que funciona con Java.

8. Portable

Al ser de arquitectura neutral es altamente portable, pero esta característica puede verse de otra manera: Los tipos estándares (int, float ...) están igualmente implementados en todas las máquinas por lo que las operaciones aritméticas funcionaran igual en todas las máquinas.

9. Alto desempeño

Al ser código interpretado, la ejecución no es tan rápida como el código compilado para una plataforma particular. El compilador Java suele ofrecer la posibilidad de compilar Bytecode en código máquina de determinadas plataformas, y según Sun este código resultar de una eficacia similar a compilaciones de C y C++.

10. Multihilos

Java puede aplicarse a la realización de aplicaciones en las que ocurra más de una cosa a la vez. Java, apoyándose en un sistema de gestión de eventos basado en el paradigma de condición y monitores C.A.R. permite apoyar la conducta en tiempo real e interactiva en programas.

11. Dinámico

Al contrario que C++ que exige se compile de nuevo la aplicación al cambiar una clase madre Java utiliza un sistema de interfaces que permite aligerar esta dependencia. Como resultado, los programas Java pueden permitir nuevos métodos y variables en un objeto de biblioteca sin afectar a los objetos dependientes.

http://www.infor.uva.es/~jmrr/TAD2003/Sesiones/TADONJava/JAVA.html

1.6 Historia de JAVA

En Diciembre de 1990, Patrick Naughton, un empleado de la empresa Sun, reclutó a sus colegas James Gosling y Mike Sheridan para trabajar sobre un nuevo tema conocido como "El proyecto verde". Este a su vez estaba auspiciado por la compañía "Sun founder Bill Joy" y tenía como objetivo principal crear un lenguaje de programación accesible, fácil de aprender y de usar, que fuera universal, y que estuviera basado en un ambiente C++ ya que había mucha frustración por la complejidad y las

Page 11: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

11

limitaciones de los lenguajes de programación existentes.

En abril de 1991, el equipo decidió introducir sistemas de software con aplicaciones para consumidores smart como plataforma de lanzamiento para su proyecto. James Gosling escribió el compilador original y lo denominó "Oak", y con la ayuda de los otros miembros del equipo desarrollaron un decodificador que mas tarde se convertiría en lenguaje Java.

Para 1992, el equipo ya había desarrollado un sistema prototipo conocido como "*7", que era una especie de cruce entre un asistente digital personalizado y un mecanismo inteligente de control remoto.

Por su parte el presidente de la compañía Sun, Scott McNealy, se dio cuenta en forma muy oportuna y estableció el Proyecto Verde como una subsidiaria de Sun. De 1993 a 1994, el equipo de Naughton se lanzó en busca de nuevas oportunidades en el mercado, mismas que se fueron dando mediante el sistema operativo base. La incipiente subsidiaria fracasó en sus intentos de ganar una oferta con Time-Warner, sin embargo el equipo concluyó que el mercado para consumidores electrónicos smart y las cajas Set-Up en particular, no eran del todo eficaces. La subsidiaria Proyecto Verde fue amortizada por la compañía Sun a mediados del 94’.

Afortunadamente, el cese del Proyecto Verde coincidió con el nacimiento del fenómeno mundial Web. Al examinar las dinámicas de Internet, lo realizado por el ex equipo verde se adecuaba a este nuevo ambiente ya que cumplía con los mismos requerimientos de las set-top box OS que estaban diseñadas con un código de plataforma independiente pero sin dejar de ser pequeñas y confiables.

Patrick Naugthon procedió a la construcción del lenguaje de programación Java que se accionaba con un browser prototipo, más tarde se le fueron incorporando algunas mejoras y el browser Hot Java fue dado a conocer al mundo en 1995.

Con el paso del tiempo el Hot Java se convirtió en un concepto práctico dentro del leguaje Java y demostró que podría proporcionar una forma segura multiplataforma para que el código pueda ser bajado y corrido del Host del World Wide Web y que de otra forma no son seguros.

Una de las características más atractivas del Hot Java fue su soporte para los "applets", que son las partes del código Java que pueden ser cargadas mediante una red de trabajo para después ejecutarlo localmente y así lograr o alcanzar soluciones dinámicas en computación acordes al rápido crecimiento del ambiente Web.

Para dedicarse al desarrollo de productos basados en la tecnología Java, Sun formó la empresa Java Soft en enero de 1996, de esta forma de se dio continuidad al fortalecimiento del programa del lenguaje Java y así trabajar con terceras partes para crear aplicaciones, herramientas, sistemas de plataforma y servicios para aumentar las capacidades del lenguaje.

Durante ese mismo mes, Java Soft dio a conocer el Java Developmet Kit (JDK) 1.0, una rudimentaria colección de componentes básicos para ayudar a los usuarios de software a construir aplicaciones de Java. Dicha colección incluía el compilador Java, un visualizador de applets, un debugger prototipo y una máquina virtual Java(JVM), necesaria para correr programas basados en Java, también incluía paquetería básica de gráficos, sonido, animación y trabajo en red.

Asimismo el Netscape Comunications Inc, mostró las ventajas de Java y rápidamente se asoció con Java Soft para explotar su nueva tecnología. No pasó mucho tiempo antes de que Netscape Communications decidiera apoyar a los Java applets en Netscape Navigator 2.0. Este fue el factor clave que lanzó a Java a ser reconocido y famoso, y que a su vez forzó a otros vendedores para apoyar el soporte de applets en Java.

Page 12: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

12

Como parte de su estrategia de crecimiento mundial y para favorecer la promoción de su nueva tecnología, Java Soft otorgó permisos a otras compañías para que pudieran tener acceso al código fuente de Java y al mismo tiempo mejorar sus navegadores , dicha licencia también les permitía crear herramientas de desarrollo para programación Java y los facultaba para acondicionar Máquinas Virtuales Java (JVM), a varios sistemas operativos.

Muy pronto las licencias o permisos contemplaban a prestigiadas firmas como IBM, Microsoft, Symantec, Silicon Graphics, Oracle, Toshiba y por supuesto Novell.

Desde su aparición, Java se ha ganado una impresionante cantidad de apoyo. Virtualmente cada vendedor importante de software ha obtenido autorización de Java y ahora ha sido incorporado en los principales sistemas operativos base de PC’s de escritorio hasta estaciones de trabajo UNIX.

Los applets Java (basados en JDK 1.02) son apoyados por los dos más populares navegadores web (Netscape Navigator 3.0 y Microsoft Internet Explorer 3.0). I.B.M./Lotus, Computer Asociates, Symantec, Informix, Oracle, Sybase y otras poderosas empresas de software están construyendo Software 100% puro JAVA, por ejemplo el Corel Office que actualmente está en versión Beta.

Un gran número de nuevas empresas ya están preparadas para recibir a la Ola Java o para ingresar a los Mercados de software basados en Java, en algunos casos como "Marimba´s Castanet" se han concebido desde un principio con bases de tecnología Java para Internet y han sido autorizados bajo licencia de Netscape para poner al corriente "netcast", un producto informativo para PC’s de escritorio.

Los nuevos proyectos de Java son co-patrocinados por cientos de millones de dólares en capital disponible de recursos tales como la Fundación Java, un fondo común de capital formado el verano pasado por 11 compañías, incluyendo Cisco Systems, IBM, Netscape y Oracle.

Los Colegios y Universidades alrededor del mundo están adoptando Java como un lenguaje universal y de enseñanza indispensable, hoy en día existen más de 150 libros en Java que se están imprimiendo en este momento.

En un reciente estudio se encontró que el 60% de los empresarios están usando Java y el 40% expresaron que Java representa la solución estratégica que estaban buscando para sus negocios..

Para darse una idea de la rápida aceptación que tiene Java en el mundo, tenemos el ejemplo de las conferencias "Java Soft Java One" en San Francisco, el primer Java One fue celebrado en abril de 1996 y atrajo a 5000 usuarios, un año después, en la segunda conferencia Java One albergó a 10,000 usuarios, asistentes. Java Soft estima que el número actual de usuarios Java llega a 400 mil y sigue creciendo. Java también está ganando aceptación en el área empresarial, se ha estimado que actualmente las compañías de hoy que cuentan con más de 5000 empleados, una tercera parte están usando Java.

1.7 Paradigma Orientado a Objetos

El siguiente texto, tomado de Wikipedia, resume el paradigma de programación orientada a objetos y da una perspectiva amplia, general y descriptiva de los aspectos que se enfrentarán a lo largo del curso (de estos apuntes) utilizando el lenguaje JAVA. La comprensión de los contenidos expuestos es fundamental en el desarrollo de este curso, así que recomiendo leerlos detenidamente.

Page 13: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

13

1.7.1 Introducción

La Programación Orientada a Objetos (POO u OOP según siglas en inglés) es un paradigma de programación que define los programas en términos de "clases de objetos", objetos que son entidades que combinan estado (es decir, datos), comportamiento (esto es, procedimientos o métodos) e identidad (propiedad del objeto que lo diferencia del resto). La programación orientada a objetos expresa un programa como un conjunto de estos objetos, que colaboran entre ellos para realizar tareas. Esto permite hacer los programas y módulos más fáciles de escribir, mantener y reutilizar.

De esta forma, un objeto contiene toda la información, (los denominados atributos) que permite definirlo e identificarlo frente a otros objetos pertenecientes a otras clases (e incluso entre objetos de una misma clase, al poder tener valores bien diferenciados en sus atributos). A su vez, dispone de mecanismos de interacción (los llamados métodos) que favorecen la comunicación entre objetos (de una misma clase o de distintas), y en consecuencia, el cambio de estado en los propios objetos. Esta característica lleva a tratarlos como unidades indivisibles, en las que no se separan (ni deben separarse) información (datos) y procesamiento (métodos).

Dada esta propiedad de conjunto de una clase de objetos, que al contar con una serie de atributos definitorios, requiere de unos métodos para poder tratarlos (lo que hace que ambos conceptos están íntimamente entrelazados), el programador debe pensar indistintamente en ambos términos, ya que no debe nunca separar o dar mayor importancia a los atributos en favor de los métodos, ni viceversa. Hacerlo puede llevar al programador a seguir el hábito erróneo de crear clases contenedoras de información por un lado y clases con métodos que manejen esa información por otro (llegando a una programación estructurada camuflada en un lenguaje de programación orientado a objetos).

Esto difiere de la programación estructurada tradicional, en la que los datos y los procedimientos están separados y sin relación, ya que lo único que se busca es el procesamiento de unos datos de entrada para obtener otros de salida. La programación estructurada anima al programador a pensar sobre todo en términos de procedimientos o funciones, y en segundo lugar en las estructuras de datos que esos procedimientos manejan. En la programación estructurada se escriben funciones y después les pasan datos. Los programadores que emplean lenguajes orientados a objetos definen objetos con datos y métodos y después envían mensajes a los objetos diciendo que realicen esos métodos en sí mismos.

1.7.2 Origen Los conceptos de la programación orientada a objetos tienen origen en Simula 67, un lenguaje diseñado para hacer simulaciones, creado por Ole-Johan Dahl y Kristen Nygaard del Centro de Cómputo Noruego en Oslo. Según se informa, la historia es que trabajaban en simulaciones de naves, y fueron confundidos por la explosión combinatoria de cómo las diversas cualidades de diversas naves podían afectar unas a las otras. La idea ocurrió para agrupar los diversos tipos de naves en diversas clases de objetos, siendo responsable cada clase de objetos de definir sus propios datos y comportamiento. Fueron refinados más tarde en Smalltalk, que fue desarrollado en Simula en Xerox PARC (y cuya primera versión fue escrita sobre Basic) pero diseñado para ser un sistema completamente dinámico en el cual los objetos se podrían crear y modificar "en marcha" en lugar de tener un sistema basado en programas estáticos.

La programación orientada a objetos tomó posición como el estilo de programación dominante a mediados de los años ochenta, en gran parte debido a la influencia de C++ , una extensión del lenguaje de programación C. Su dominación fue consolidada gracias al auge de las Interfaces gráficas de usuario, para los cuales la programación orientada a objetos está particularmente bien adaptada. En

Page 14: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

14

este caso, se habla también de programación dirigida por eventos.

Las características de orientación a objetos fueron agregadas a muchos lenguajes existentes durante ese tiempo, incluyendo Ada, BASIC, Lisp, Pascal, y otros. La adición de estas características a los lenguajes que no fueron diseñados inicialmente para ellas condujo a menudo a problemas de compatibilidad y a la capacidad de mantenimiento del código. Los lenguajes orientados a objetos "puros", por otra parte, carecían de las características de las cuales muchos programadores habían venido a depender. Para saltar este obstáculo, se hicieron muchas tentativas para crear nuevos lenguajes basados en métodos orientados a objetos, pero permitiendo algunas características imperativas de maneras "seguras". El Eiffel de Bertrand Meyer fue un temprano y moderadamente acertado lenguaje con esos objetivos pero ahora ha sido esencialmente reemplazado por Java, en gran parte debido a la aparición de Internet, y a la implementación de la máquina virtual de Java en la mayoría de navegadores.

1.7.3 Diferencias con la programación estructurada

Aunque la programación estructurada (a veces llamada procedural o procedimental) condujo a mejoras de la técnica de programación secuencial, los métodos modernos de diseño de software orientado a objetos incluyen mejoras entre las que están el uso de los patrones de diseño, diseño por contrato, y lenguajes de modelado (ej: UML).

Las principales diferencias entre la programación estructurada y la orientada a objetos son:

• La programación orientada a objetos es más moderna, es una evolución de la programación estructurada que plasma en el diseño de una familia de lenguajes conceptos que existían previamente con algunos nuevos.

• La programación orientada a objetos se basa en lenguajes que soportan sintáctica y semánticamente la unión entre los tipos abstractos de datos y sus operaciones (a esta unión se la suele llamar clase).

• La programación orientada a objetos incorpora en su entorno de ejecución mecanismos tales como el polimorfismo y el envío de mensajes entre objetos.

Erróneamente se le adjudica a la programación estructurada clásica ciertos problemas como si fueran inherentes a la misma. Esos problemas fueron haciéndose cada vez más graves y antes de la programación orientada a objetos diversos autores (de los que podemos destacar a Yourdon) encontraron soluciones basadas en aplicar estrictas metodologías de trabajo. De esa época son los conceptos de cohesión y acoplamiento. De esos problemas se destacan los siguientes:

• Modelo mental anómalo. Nuestra imagen del mundo se apoya en los seres, a los que asignamos nombres sustantivos, mientras la programación clásica se basa en el comportamiento, representado usualmente por verbos.

• Es difícil modificar y extender los programas, pues suele haber datos compartidos por varios subprogramas, que introducen interacciones ocultas entre ellos.

• Es difícil mantener los programas. Casi todos los sistemas informáticos grandes tienen errores ocultos, que no surgen a la luz hasta después de muchas horas de funcionamiento.

• Es difícil reutilizar los programas. Es prácticamente imposible aprovechar en una aplicación

Page 15: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

15

nueva las subrutinas que se diseñaron para otra.

• Es compleja la coordinación y organización entre programadores para la creación de aplicaciones de media y gran envergadura.

En la programación orientada a objetos pura no deben utilizarse llamadas de subrutinas, únicamente mensajes.

Por ello, a veces recibe el nombre de programación sin CALL, igual que la programación estructurada se llama también programación sin GOTO.

Sin embargo, no todos los lenguajes orientados a objetos prohíben la instrucción CALL (o su equivalente), permitiendo realizar programación híbrida, imperativa y orientada a objetos a la vez.

1.7.4 La Programación Orientada a Objetos (POO) como solución La programación orientada a objetos es una nueva forma de programar que trata de encontrar solución a estos problemas. Introduce nuevos conceptos, que superan y amplían conceptos antiguos ya conocidos. Entre ellos destacan los siguientes:

• Objeto: entidad provista de un conjunto de propiedades o atributos (datos) y de comportamiento o funcionalidad ("métodos"). Corresponden a los objetos reales del mundo que nos rodea, o a objetos internos del sistema (del programa).

• Clase: definiciones de las propiedades y comportamiento de un tipo de objeto concreto. La instanciación es la lectura de estas definiciones y la creación de un objeto a partir de ellas.

• Método: algoritmo asociado a un objeto (o a una clase de objetos), cuya ejecución se desencadena tras la recepción de un "mensaje". Desde el punto de vista del comportamiento, es lo que el objeto puede hacer. Un método puede producir un cambio en las propiedades del objeto, o la generación de un "evento" con un nuevo mensaje para otro objeto del sistema.

• Evento: un suceso en el sistema (tal como una interacción del usuario con la máquina, o un mensaje enviado por un objeto). El sistema maneja el evento enviando el mensaje adecuado al objeto pertinente. También se puede definir como evento, a la reacción que puede desencadenar un objeto, es decir la acción que genera.

• Mensaje: una comunicación dirigida a un objeto, que le ordena que ejecute uno de sus métodos con ciertos parámetros asociados al evento que lo generó.

• Propiedad o atributo: contenedor de un tipo de datos asociados a un objeto (o a una clase de objetos), que hace los datos visibles desde fuera del objeto, y cuyo valor puede ser alterado por la ejecución de algún método.

• Estado interno: es una propiedad invisible de los objetos, que puede ser únicamente accedida y alterada por un método del objeto, y que se utiliza para indicar distintas situaciones posibles para el objeto (o clase de objetos).

• Componentes de un objeto:atributos, identidad, relaciones y métodos.

• Representación de un objeto: un objeto se representa por medio de una tabla o entidad que esté compuesta por sus atributos y funciones correspondientes.

En comparación con un lenguaje imperativo, una "variable", no es más que un contenedor interno del atributo del objeto o de un estado interno, así como la "función" es un procedimiento interno del método del objeto.

Page 16: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

16

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

• Abstracción: Cada objeto en el sistema sirve como modelo de un "agente" abstracto que puede realizar trabajo, informar y cambiar su estado, y "comunicarse" con otros objetos en el sistema sin revelar cómo se implementan estas características. Los procesos, las funciones o los métodos pueden también ser abstraídos y cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción.

• Encapsulamiento: Significa reunir a todos los elementos que pueden considerarse peretenecientes a una misma entidad, al mismo nivel de abstracción. Esto permite aumentar la cohesión de los componentes del sistemas. Algunos autores confunden este concepto con el principio de ocultación, principalmente porque se suelen emplear conjuntamente.

• Principio de ocultación: Cada objeto está aislado del exterior, es un módulo natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas, solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no pueden cambiar el estado interno de un objeto de maneras inesperadas, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce a un agregado o rompecabezas de objetos.

• Polimorfismo: comportamientos diferentes, asociados a objetos distintos, pueden compartir el mismo nombre, al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. O dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en "tiempo de ejecución", esta última característica se llama asignación tardía o asignación dinámica. Algunos lenguajes proporcionan medios más estáticos (en "tiempo de compilación") de polimorfismo, tales como las plantillas y la sobrecarga de operadores de C++.

• Herencia: las clases no están aisladas, sino que se relacionan entre sí, formando una jerarquía de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento permitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que reimplementar su comportamiento. Esto suele hacerse habitualmente agrupando los objetos en clases y estas en árboles o enrejados que reflejan un comportamiento común. Cuando un objeto hereda de más de una clase se dice que hay herencia múltiple; esta característica no está soportada por algunos lenguajes (como Java).

http://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos

Page 17: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

17

Capítulo 2 Primeros programas y aspectos básicos

2.1 Primer programa

Construiremos un primer programa que muestra en pantalla un texto. Notar que el texto va entre comillas dobles.

Para probar nuestro programa debemos primero escribirlo en una archivo de texto con el nombre Bienvenido.java, y luego compilarlo y ejecutarlo.

Tener cuidado de:

- El nombre del archivo debe ser idéntico al del programa, el cual es definido en la línea 6 public class Bienvenido. En este caso el nombre del programa es Bienvenido, pero podría ser cualquiera. Un programa definido como public class Hola, debe escribirse en un archivo Hola.java.

- En JAVA, las letras minúsculas y mayúsculas son diferentes. JAVA es “case-sensitive”.

- En ambientes Windows, el sistema puede estar configurado para “Ocultar extensiones para tipos de archivos conocidos”. Si esto está activado, debemos cuidar que el archivo creado sea efectivamente Bienvenido.java y no Bienvenido.java.txt.

2.1.1 Comentarios Un comentario es un texto dentro del programa para que el compilador ignora al encontrar cierto tipo de marcas. Los comentarios son usados especialmente para explicar el programa “insitu”. En JAVA pueden definirse comentarios usando “//”, lo cual marca como comentado (“comenta”) todo el texto hacia la derecha hasta el fin de línea, o usando los delimitadores “/*” y “*/”, lo que comenta todo el texto que esté entre ellos.

Notar como usando comentarios hemos explicado cada parte del programa.

2.1.2 Salida de información con el objeto System.out La línea 11 del programa utiliza una funcionalidad de salida de texto: println(), que está disponible desde el objeto System.out. En JAVA, las funcionalidades se denominan métodos y siempre son definidas y ejecutadas desde objetos o clases. Veremos más detalles sobre los métodos en los siguientes capítulos.

Page 18: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

18

En general, las entradas y salidas de información son denominadas flujos, y pueden comunicar el programa no sólo con la pantalla, sino que también, con otros medios o dispositivos: archivos (almacenamiento), sonido, etc.

Los métodos (o funcionalidades) siempre llevan paréntesis. Probar invocar el método de la siguiente manera System.out.println;

Ocurre un error. Debe invocarse el método de la siguiente manera: System.out.println();

2.1.3 Errores comunes - Cada instrucción termina en punto y coma, obviar estos de limitadores es un error de sintaxis.

- Cada bloque abierto con “{” debe ser cerrado con “}”.

- Las instrucciones deben escribirse tal cual, considerando que JAVA es “case-sensitive”. Si escribimos, por ejemplo Public class … incurrimos en error, la palabra reservada es public y no Public.

- Cuidar reconocer bien las letras. Con tipografías como Courier, la diferencia entre los caracteres 1 (uno) y l (ele) son mínimas.

2.1.4 Algunas modificaciones Probar ahora hacer las siguientes modificaciones (los comentarios repetidos del programa anterior se han omitido):

Se han usado caracteres especiales dentro del texto:

\n : Salto de línea

\t: tabulador

¿Podrías explicar la diferencia entre los métodos println() y print().

El siguiente programa introduce la utilización de una variable. La variable String vtexto reserva una localización de memoria donde el texto “Este es un texto cualquiera” es almacenado (la variable se ha bautizado vtexto pensando en que es una variable de texto). Notar la diferencia entre las líneas 9 y 10.

Page 19: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

19

2.2 Uso de Objetos y Clases

Los ejemplos anteriormente mostrados utilizan objetos para cumplir su funcionalidad. Específicamente el objeto out de la clase System. Veamos el siguiente ejemplo que muestra un texto en un cuadro de diálogo. Para lograr esta funcionalidad utilizaremos la clase JOptionPane, que implementa varias funcionalidades para mostrar ventanas de diálogo. Notar que es necesario indicarle al programa que incluya o importe hacia sí, las clase JOptionPane (que está ubicada en el paquete javax.swing).

La forma en que el programa funciona es modular. La tarea de desplegar el cuadro de diálogo (dibujarlo y mostrarlo) es responsabilidad del método showMessageDialog() de la clase JOptionPane. La siguiente figura muestra la relación entre nuestro programa y otras clases y objetos.

String vtexto

JOptionPane

main()

showMessageDialog()

crear

invocar

pasa como parámetro

String vtexto

JOptionPane

main()

showMessageDialog()

crear

invocar

pasa como parámetro

Page 20: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

20

2.3 Flujos de Entrada: ingresar datos al programa desde teclado

El siguiente ejemplo muestra cómo ingresar texto al programa y almacenarlo en una variable. El proceso no es trivial, sin embargo es útil para comprender mejor los flujos de datos. Luego aprenderemos formas más sencillas de hacerlo.

Analicemos el programa:

- Línea 8: el método “arroja hacia fuera” los posibles errores de entrada salida (IOException). JAVA posee un excelente mecanismo de manejo y control de errores, los cuales se denominan excepciones. En este caso, la lectura de datos desde el teclado “puede” generar errores. Para simplificar, obviamos el manejo de errores incluyendo la instrucción throws IOException en el encabezado del método main().

- Línea 9: se crea el objeto stdin (el nombre podría ser cualquiera, lo hemos llamado asi por Standar Input) de la clase BufferedReader. Esta clase define mecanismos de lectura de información sobre flujos de entrada (InputStreamReader). System.in indica que se utilizará la entrada estándar (la entrada podría ser otra, distinta del teclado: mouse, micrófono, conexión a red, eventos de pantalla, etc.).

- Línea 11: usando el método readLine() del objeto stdin, el programa queda a la espera de que el usuario presione la tecla enter. Todo lo que el usuario escribió en la pantalla antes de presionar enter queda almacenado en la variable vnombre.

- Línea 12: Se ha utilizado el operador “+” entre textos. En este caso, el operador produce la concatenación de los textos a su izquierda y derecha. El resultado de la concatenación es almacenado en la variable vsaludo.

El siguiente ejemplo muestra la utilización de otro método de la clase JOptionPane para recibir la información. Esto tiene varias ventajas: a) es más presentable y cómodo para el usuario, b) facilita la programación, es más sencillo, y c) resuelve el problema de codificación de caracteres para mostrar acentos y ‘ñ’s (probar imprimir acentos o ‘ñ’s con el métodos System.out.println()).

Page 21: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

21

Notar que:

- showInputDialog() muestra un cuadro de dialogo con una caja de texto.

- Hemos obviado crear la variable vsaludo y hemos concatenado el texto “Hola “ y la variable vnombre inmediatamente al invocar el método showMessageDialog().

- La instrucción System.exit(0) termina el programa. En este caso, el programa termina apenas el usuario cierra el cuadro de diálogo.

2.4 Variables y Tipos de datos primitivos

Una variable es una estructura que permite almacenar y acceder información en memoria durante la ejecución de un programa. Dependiendo de la naturaleza de la información, las variable están asociadas a tipos de dato específicos.

En forma general, los tipos de datos caen dentro de tres grandes grupos: números enteros, números reales (con decimales) y caracteres y cadenas de caracteres (texto). En varios lenguajes aparece un tipo de datos lógico o boolean para valores verdadero/falso.

En algunos lenguajes de programación, el programador no necesita especificar o decidir el tipo de dato a utilizar en cada variable que crea; en JAVA, en cambio, esto es absolutamente necesario.

En JAVA existen los siguientes tipos de datos, los que reciben también el nombre de tipos de datos primitivos:

TIPO DESCRIPCION BITS RANGO (valores posibles) byte Número entero de 1 byte 8 -128 127 short Número entero 16 -32.768 32.767 int Número entero 32 -2.147.483.648 2.147.483.647 long Número entero largo 64 -2-63 263 – 1 float Número real, punto flotante de

precisión simple 32 10-46 1038

double Número real, punto flotante de precisión doble

64 10-324 10308

char Caracter 16 todos los caracteres según codificación UNICODE (http://www.unicode.org/).

boolean Lógico, booleano - true, false

Page 22: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

22

Los tipos de datos primitivos se distinguen de los tipos definidos por el usuario a partir de Clases. La creación de objetos de una Clase es análoga a la declaración de variables de un tipo de dato.

2.4.1 Declaración y uso de variables Para crear variables en JAVA debemos anteponer el tipo de datos al nombre de la variable a crear. Por ejemplo se desea crear la variable "letra" de tipo char: char letra;

La creación de la variable se conoce también como declaración. Notar que no se ha especificado ningún valor a almacenar. Alternativamente, podemos especificar un valor junto a la declaración de la variable: char letra2 = 'a';

Luego de tener la variable definida, podemos cambiar su valor: letra = 'b'; letra2 = 'w';

Tomar en cuenta las siguientes consideraciones:

- Las variables pueden declararse sólo una vez dentro de un bloque.

- Al asignar un valor fuera del rango a una variable se produce desbordamiento (overflow). Investigar.

- El tipo char permite representar caracteres de a uno y no cadenas de caracteres (texto). Para esto utilizamos objetos del tipo String, que no es precisamente un tipo de datos primitivo, sino una clase.

- Los datos de tipo char van entre comillas simples y consideran todos los símbolos UNICODE.

- Los datos de tipo numérico con decimales consideran el punto como separador decimal, a menos que se especifique explícitamente otro carácter separador en las transformaciones de y desde cadenas de caracteres.

Las siguientes instrucciones muestran como crear variables de distintos tipos, asignando valor inmediatamente:

byte n1 = 100; short n2 = 12530;

int a = 1270; boolean cierto = false; long b = 46252356; float f1 = 5263.344F; double d1 = 312323423.65686;

char simbolo = '%';

2.4.2 Tipo de datos String Comunmente los programas computacionales deben procesa texto. Es por esto que los lenguajes de programación proveen tipos de datos cadena y funciones de procesamientos de cadenas. El término cadena se refiere a la estructura de datos que permite almacenar una secuencia de caracteres.

Page 23: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

23

En JAVA existe la clase String que permite crear y manipular cadenas de caracteres como objetos. Sin embargo, la implementación de la clase String es especial y permite tratar objetos String casi como variables de tipo primitivo.

Almacenamiento de una cadena String saludo = "Hola!, este es un texto cualquiera";

La cadena almacenada en la variable saludo contiene la secuencia de caracteres "Hola!, este es un texto cualquiera". Cada carácter ocupa una posición específica de la secuencia, contando desde 0.

H o l a ! , e s t e e s u n t e x t o c u a l q u i e r a

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

Notar que las cadenas se especifican entre comillas dobles (").

La clase String implementa una serie de métodos que facilitan el tratamiento de cadenas, por ejemplo: char letra = saludo.charAt(5); char letraespacio = saludo.charAt(6); int pos = saludo.indexOf('t'); int pos2 = saludo.indexOf("texto"); int largo = saludo.length();

letra2 queda con el valor 'o', letra queda con el valor ',', letraespacio queda con el valor ' ', pos queda con el valor 9, pos2 queda con el valor 18 y largo con el valor 34.

Una de las acciones básicas para procesar cadenas es recorrer un String. El siguiente programa muestra como "recorrer" una cadena.

public class Recorre{ public static void main(String[] args){ String hola = "Hola a todos"; int largo = hola.length(); for (int i=0;i<largo;i++){ System.out.println(hola.charAt(i)); } } }

2.5 Operaciones

Para cada tipo de datos existen operaciones distintas. Las operaciones aritméticas básicas (suma, resta, multiplicación y división) se aplican a tipos numéricos. Considerar que la división (/) es entera si los operandos son ambos números enteros, y es con decimales si alguno de los operandos en float o double. Las operaciones con cadenas de caracteres y caracteres

Page 24: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

24

El siguiente cuadro muestra operaciones básicas para diversos tipos de datos.

Operador Datos Acción String Concatenación: unión de texto. �número Suma. número antepuesto a un operando, invierte el signo del número. �número Resta.

* número Multiplica y tiene prioridad sobre la suma y resta. / número Divide y tiene prioridad sobre la suma y resta.

% número Devuelve el resto de la división entera del operador derecho por el izquierdo. �

lógico El operador lógico ����� . && lógico El operador AND condicional. || lógico El operador OR condicional. �� Cualquier El operador condicional de igualdad, devuelve verdadero si derecha e

izquierda es lo mismo. < Básicos Menor que, devuelve verdadero si izquierda es menor que derecha.

<= Básicos Menor o igual que, devuelve verdadero si izquierda es menor o igual que derecha.

> Básicos Mayor que, devuelve verdadero si izquierda es mayor que derecha.

>= Básicos Mayor o igual que, devuelve verdadero si izquierda es mayor o igual que derecha.

� Cualquier Asigna al elemento de la izquierda, el de la derecha.

var++ Básicos Incrementa en uno la variable var. var-- Básicos Decrementa en uno la variable var.

Generalmente, el resultado de una operación es del tipo más genérico de los operandos. La suma entre un int y un double dará como resultado un double. La concatenación de un String y un char devolverá un String.

Las operaciones ==, <, >, etc., son llamadas operaciones de comparación y devuelven un valor boolean (true o false).

El siguiente programa ayuda a comprender las operaciones con números y cadenas. Pruébelo ingresando números enteros positivos y negativos.

Page 25: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

25

2.5.1 Precedencia de operadores La precedencia de operadores se cumple de la siguiente manera. Consideremos la siguiente instrucción: int a = 10 * 9 / 3 – 5 + 6 % 4 / 2;

Las operaciones se realizan en el siguiente orden:

1) 10 * 9

2) 90 / 3

3) 6 % 4

4) 2 / 2

5) 30 – 5

6) 25 + 1

Resultado 26

Lo que es análogo a int a = (((10 * 9) / 3) – 5) + ((6 % 4) / 2);

2.5.2 Overflow Si tratamos de asignar un valor numérico a una variable cuyo tipo de datos no alcanza para representar tal magnitud ocurre overflow. No podemos asignar el número 800 a una variable de tipo byte (que sólo permite números en el rango -128 a 127) sin incurrir en un error. Para la mayoría de los casos, el compilador de JAVA es suficiente para detectar posibles problemas y detener la compilación. Sin embargo el overflow puede ocurrir fácilmente en operaciones como lo que se muestra a continuación:

En este caso, esperaríamos que el programa imprima 1000. Sin embargo imprime 5!!!

La explicación es overflow: a pesar que el tipo long permite almacenar el resultado de la operación

24 * 60 * 60 * 1000 * 1000

las multiplicaciones se realizan almacenando los susesivos resultados temporalmene en variables int. Esto ocurre ya que, a menos que especifiquemos lo contrario, las operaciones con números enteros se realizan como operaciones int y no long.

La solución es sencilla y consiste en incluir al lado derecho de la asignación, un número de tipo long. Con esto, forzamos a que la operación se realice por completo con este tipo de datos (notar que la letra L como sufijo del primer número, lo convierte a long):

Page 26: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

26

2.6 Conversión básica entre tipos de datos distintos

En JAVA es necesario tener en cuenta que variables de distinto tipo son, en principio, incompatibles. Esto significa que si, por ejemplo, queremos que en un programa se ingresen cantidades numéricas, debamos convertir a algún tipo apropiado el texto que el usaurio ingresa. Tener siempre en cuenta que una cadena como "1056" es distinta a la cantidad 1056.

En JAVA existen varios tipos de conversiones entre tipos de datos distintos.

2.6.1 Conversión automática Para datos de tipo numérico, el resultado de una operación entre datos de distinto tipo generará un dato del tipo con mayor representación. Por ejemplo: byte n1 = 100; short n2 = 12530; float f1 = 5263.344F; float f2 = f1 + n2 + n1 + a;

En el caso de operar números con cadenas, la operación posible es la concatenación donde los números son automáticamente convertidos a su representación como cadenas de caracteres. String hola = "Hola!"; String nombre = "Bart Simpson"; int edad = 10; String saludo = hola + " Soy " + nombre + " y mi edad es " + edad + " años.";

2.6.2 Clases Asociadas con Tipos Primitivos En JAVA existen Clases construidas para facilitar el manejo de datos numéricos, caracteres y lógicos. Las clases Byte, Short, Integer, Long, Float y Double implementan una serie de métodos para el manejo de números enteros y reales. Las Clases Boolean y Character hacen lo suyo con lo tipos de datos lógicos y caracteres.

Todas estas clases están en el paquete java.lang (ver API). Nótese que las Clases se distinguen fácilmente de los tipos primitivos al comenzar con una letra mayúscula: Double y double, Boolean y boolean.

Dentro de las funcionalidades que estas Clases proveen está la transformación de tipos. Por ejemplo, para transformar una cadena que representa un número real a un double y luego viceversa, haríamos: String cad = "934.52"; double num1 = Double.parseDouble(cad); String cad2 = Double.toString(num1);

El siguiente ejemplo muestra un programa que pide el nombre y la edad al usuario y muestra un mensaje dependiendo del dato edad.

Page 27: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

27

Se realiza una conversión en la línea 12. El texto ingresado por el usuario y almacenado en la variable vedad es convertido en un int. Este programa no verifica que lo que el usaurio ha ingresado sean sólo dígitos, y en el caso que no lo hiciera, la conversión arrojará una excepción.

2.7 Estructura de control condicional (if - else)

En el programa anteriormente expuesto se introduce una estructura de control que permite al algoritmo seguir dos caminos distintos evaluando una condición. En general la instrucción if-else tiene la siguiente forma:

Al igual que en una Clase o un método, los símbolos "{" y "}" delimitan bloques de ejecución. Los delimitadores de bloque pueden obviarse si el bloque sólo contiene una instrucción (no olvidar el punto y coma luego de la instrucción).

La cláusula else es opcional.

El siguiente ejemplo muestra el uso de la sentencia if

Page 28: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

28

2.7.1 Cuidar la indentación Indentación es un anglicismo de uso común en informática. Por indentación se entiende mover un bloque de texto hacia la derecha insertando espacios o tabuladores para separarlo del texto adyacente.

En los lenguajes de programación de computadoras, la indentación se utiliza para mejorar la legibilidad del código fuente por parte de los programadores, teniendo en cuenta que los compiladores o intérpretes raramente consideran los espacios en blanco entre las sentencias de un programa. Sin embargo, en ciertos lenguajes de programación como Haskell, Occam y Python, la indentación se utiliza para delimitar la estructura del programa permitiendo establecer bloques de código.

Fuente: Wikipedia

Considerar que en JAVA la indentación no tiene significado semántico. ¿Qué imprime este programa?

Pudiera parecer que el bloque else acompaña a la primera cláusula if. Sin embargo el programa no imprime nada, ¿puedes explicarlo?

Page 29: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

29

Recomendación: indente adecuadamente sus programas. Cuide que los bloques dentro de otros bloques tengan una sangría. Por ejemplo, el mismo programa anterior es presentado si identación. La funcionalidad del programa es la misma, funciona igual, pero es difícil de entender:

Una mala indentación puede llevar fácilmente al programado a cometer errores.

Page 30: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

30

2.8 Ejemplos desarrollados

2.8.1 Numero par Escribir un programa que pida al usuario un número entero y muestre si es impar o par.

Solución 1:

Un número impar es un número que dividido por 2 da resto 1. Usando el operador de módulo '%' resolvemos esto fácilmente. El siguiente programa implementa este algoritmo.

¿Funciona bien? Pruebe con número negativos, por ejemplo el -5. ¿Qué ocurre? El programa se comporta bien para todos los enteros positivos, en efecto si el resto de la división es 1, el núemro es impar. Sin embargo, el resto de la división de un número impar negativo por 2 es -1!!!!

Solución 2:

El problema puede corregirse cambiando la comparación e invirtiendo los mensajes.

Page 31: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

31

2.8.2 Factor Constuya un programa que verifique si unnúmero es factor de otro. El programa debe pedir al usuario los números.

Solución 1:

El programa es similar al anterior mostrado y utiliza el operador '%' para calcular el residuo de la división de los números. Luego compara el residuo con 0.

¿Qué ocurre si ingresamos por segundo número un 0? Corrija el programa para que verifique esta situación.

Solución 2:

Antes de preguntar por el resto de num1 dividido en num2, verificamos que num2 sea distinto de 0.

Page 32: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

32

2.8.3 Conversor de Temperatura Escriba un programa que convierta medidas de temperatura en grados Celsius, Fahrenhait y Kelvin. El usuario ingresará el valor de la temperatura anteponiendo la letra F, C o K dependiendo del sistema de medida. El programa convertirá el valor a los otros sistemas y mostrará la temperatura en las 3 escalas.

Solución:

Usaremos JOptionPane.showInputDialog para pedir el valor de la temperatura y lo almacenaremos en una variable (strtemp). Luego obtenemos el primer caracter de la cadena usando el método charAt de la clase String. Para obtener la temperatura utilizamos el método substring que nos permite extraer una porción de la cadena.

Modificaciones propuestas:

- Modifique el programa para que verifique rangos reales para la temperatura de entrada.

- Incluya un mensaje si la primera letra de lo ingresado no es 'C', 'K' o 'F'.

- Modifique el programa para que permita ingresar las temperaturas anteponiendo 'c', 'k' o 'f'.

Page 33: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

33

2.9 Ejercicios

1. Especifique el tipo de datos que utilizaría para la siguiente información

a. La velocidad de la luz (m/s). b. Nombres y apellidos c. Separador decimal d. Edad e. Teléfonos f. Estado civil (casado(a) / soltero(a)) g. RUTs h. La calificación o nota en una prueba i. Tasa de interés anual j. Bits por segundos de una conexión por modems k. Datos hexadecimales l. Datos binarios m. Poblaciones humanas n. Posición de un pixel en una pantalla o. Índice de la posición de un caracter en una cadena p. Sexo femenino o masculino.

2. Indique los errores que existen en los siguienets trozos de código: String nombre = "Fulano"; char ultimaletra = nombre.charAt(nombre.length()); short a = -12315; int b = a*2; short c = a*3; int numero = 0.12*9.8; byte misbits; byte misbits = 200; short n1 = -5; int res = 9 + (n1 < 0)*2 + "10";

3. Analizando el siguiente programa, ¿cuál es el valor mostrado de la cadena procesada? import javax.swing.JOptionPane; public class Recorre2{ public static void main(String[] args){ String frase = "El caballo blanco de napoleón"; int largo = frase.length(); String procesada = ""; for (int i=0;i<largo;i++){ char letra = frase.charAt(i); if (letra == ' '){ procesada = "." + procesada; } else{ procesada = letra + procesada; } } procesada = largo + procesada; JOptionPane.showMessageDialog(null,procesada,

"Procesamiento de cadenas",JOptionPane.PLAIN_MESSAGE); } }

Page 34: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

34

4. Construya un programa que imprima en pantalla la siguiente figura:

5. Construya un programa que cuente todas los caracteres 'a' de una cadena ingresada por el usuario.

6. Construya un programa que lea tres números enteros y que los reste si el primero es mayor que el segundo, los multiplique si el primero es menor que el segundo y los sume si son iguales.

7. En un almacén se hace un 12% de descuento a los clientes cuya compra supere los $10000 ¿Cuál será la cantidad que pagará una persona por su compra? Construya un programa que lea el monto de la compra y calcule el precio final.

8. Un obrero necesita calcular su salario semanal, el cual se obtiene de la sig. manera:

a. Si trabaja 40 horas o menos se le paga $1600 por hora

b. Si trabaja más de 40 horas se le paga $1600 por cada una de las primeras 40 horas y $2000 por cada hora extra.

Construya un programa que lea las horas trabajadas e imprima en consola el salario semanal.

9. Una serie de impuestos específicos se aplican sobre el valor de un artículo. Al valor bruto se descuentan un 10% del impuesto A y 5,5% del impuesto B. Al valor que queda se le aplica un impuesto del 11,4%. Construya un programa que reciba el valor bruto y devuelva el valor neto final.

Page 35: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

35

Capítulo 3 Control del Programa En este capítulo estudiaremos algunas técnicas básicas para resolver problemas usando algoritmos. El concepto de algoritmo se define en términos de:

• acciones que se ejecutan

• el orden de ejecución de dichas acciones

Llamamos control del programa a la especificación del orden de las acciones (o instrucciones) y podemos escribirlo en base a estructuras de control.

Analizaremos las estructuras de control con ejemplos e introduciremos los Diagramas de Actividad del Lenguaje de Modelamiento Unificado, UML (Unified Modeling Language) para describirlas en forma gráfica. Utilizaremos pseudocódigo y luego traduciremos los ejemplos a lenguaje JAVA. El pseudocódigo es un lenguaje informal, no es un lenguaje de computadores, pero se asemeja a ellos. El pseudocódigo permite a los programadores desarrollar algoritmos sin preocuparse de las particularidades del lenguaje.

Por lo general, en un programa las instrucciones se ejecutan una después de otra en el orden en que están escritas. Este proceso se conoce como ejecución secuencial. Varias instrucciones en Java permiten al programador especificar que la siguiente instrucción a ejecutarse tal vez no sea la siguiente en la secuencia. Esto se conoce como transferencia de control.

Durante la década del sesenta, se hizo evidente que el uso indiscriminado de las transferencia de control era el origen de muchas de las dificultades que experimentan los grupos de desarrollo de software. A quien se señaló como culpable fue a la instrucción goto (utilizada en varios lenguajes de programación, incluyendo C y Basic), la cual permite al programador especificar la transferencia de control a uno de los muchos posibles destinos dentro del programa. La noción de la llamada programación estructurada se hizo casi sinónimo de la "eliminación del goto".

Las investigaciones de Bohn y Jacopini* demostraron que los programas podían escribirse sin las instrucciones goto. El reto de la época para los programadores fue cambiar sus estilos a una "programación sin goto". No fue hasta la década de los setenta que los programadores tomaron en serio la programación estructurada. Los resultados fueron impresionantes, a medida que los grupos de desarrollo de software reportaron reducciones en los tiempos de desarrollo, mayor incidencia de las entregas de sistemas a tiempo y más proyectos de software finalizados sin salirse del presupuesto. La calve de estos logros fue que los programas estructurados eran más claros, más fáciles de depurar y modificar, y había más probabilidad de que estuvieran libres de errores desde el principio.

El trabajo de Bohm y Jacopini demostró que todos los programas podían escribirse en términos de tres estructuras de control solamente: la estructura secuencial, la estructura de selección y la estructura de repetición.

Texto tomado de Java Como Programar 5ta Edición, Deitel. Páginas 105 y 106 (4.4 Estructuras de Control)

* Bohm, C. y G. Jacopini, "Flow Diagrams, Turing Machines and Languajes with Only Two Formation Rules", Communications of the ACM, Vol. 9, No. 5, Mayo de 1996, páginas 336,371.

Page 36: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

36

3.1 Estructura de Control Secuencial

En JAVA, como en la mayoría de los lenguajes de programación, la estructura secuencial está integrada de manera transparente: la siguiente instrucción que se ejecuta es la que está escrita inmediatamente después.

3.2 Estructuras de Control de Selección

En el capítulo anterior hemos analizado la estructura de selección o condicional if – else que nos permite separar el flujo del programa evaluando condiciones, en otras palabras, lograr que el programa haga cosas distintas dependiendo de algo.

Diagrama de Actividad que representa la estructura secuencial de un algoritmo muestra el resultado de la multiplicación de dos números pedidos al usuario.

En los diagramas de actividad, el círculo negro representa el inicio del algoritmo, el círculo negro con borde blanco representa el fin, las flechas indican el flujo del programa y los cuadros con extremos semicirculares son las acciones. Los recuadros con la esquina superior derecha "doblada" son comentarios en UML.

Page 37: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

37

3.3 Estructuras de control cíclicas

Las estructuras de repetición (o cíclicas o de bucle) permiten repetir bloques de ejecución dentro del flujo del programa. Veamos un ejemplo. Supongamos que deseamos escribir un algoritmo que muestre la tabla de multiplicar del 8. En pseudocódigo: Inicio Inicializar variable NUM en 1 Repetir mientras NUM sea menor o igual a 12 mostrar (NUM * 8) incrementar NUM en uno fin

Consideramos que todas las líneas que están indentadas a la derecha bajo la línea Repetir… son el bloque que se repite mientras se cumple la condición.

Diagrama de Actividad que representa un programa que verifica si un número es par o impar. El rombo representa la estructura de sección, una bifurcación del flujo dependiendo del resto de la división.

Page 38: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

38

En JAVA

En general la estructura while en JAVA es:

Averiguar:

Existe una variación de la estructura while, el do/while. Investigar cómo utilizar y en qué casos conviene.

3.3.1 Repeticiones controladas por contador El ejemplo anterior muestra la estructura de control while (mientras) y la técnica básica de repetición o bucle controlado por contador: el control, es decir, el cuando parar de repetir depende del valor de la variable NUM, que es un contador de las repeticiones del bucle (en cada vuelta se incrementa).

Veamos otro ejemplo: en el capítulo anterior vimos como recorrer una cadena. Recordando, una cadena, una variable de tipo String es una secuencia ordenada de caracteres. Cada carácter ocupa una

Diagram de actividad que representa una estructura de repetición while

Page 39: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

39

posición del String y por lo tanto podemos recorrer una cadena accediendo a los caracteres desde la primera hasta la última posición:

Por cada posición, P, desde la primera hasta la última mostrar el carácter en la posición P

Tomando en cuenta que la primera posición es siempre 0 y la última es un número antes del largo de la cadena (la cantidad de caracteres), el algoritmo quedaría:

Por cada posición, P, desde 0 hasta (largo cadena - 1) mostrar el carácter en la posición P

Para implementar este algoritmo deberá haber una variable que mantenga la posición actual de la cadena y que en cada vuelta se incremente. Esta variable será el contador que controle el bucle. En JAVA existe una estructura conocida como for que facilita la definición de bucles controlados por contador. El siguiente programa recorre una cadena ingresada por el usuario usando esta estructura de control:

Notar como el bucle continua mientras el contador (i) es menor que el largo de la cadena. El largo de la cadena no lo sabemos a priori, pues es ingresada en tiempo de ejecución por el usuario. Notar además que la instrucción para definir la variable contadora y para incrementarla al final de cada vuelta están incluidas en la misma línea de la instrucción de la estructura for.

La estructura for contiene 3 instrucciones: inicialización del contador (A), condición de repetición (B) e incremento del contador (C).

Ninguan de estas 3 instrucciones es obligatoria, podíamos tener un programa como este:

Page 40: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

40

Importante: este programa no tiene condición definida por lo que seguirá en forma infinita. Para detener la ejecución en ambientes Windows es necesario cerrar la ventana de ejecución.

3.3.2 Repeticiones controladas por centinela

Veamos ahora el siguiente ejemplo: se desea un programa que permita al usuario adivinar un número entre 1 y 10. El programa debe preguntar por el número secreto hasta que el usuario lo adivine y luego mostrar cuantos intentos realizó. En el ejemplo el número secreto es el 6. Es obvio que será secreto sólo si el usuario no ve el código fuente. Inicio Inicializar NUMERO_SECRETO en 6 Inicializar NUMERO_INTENTOS en 0 Inicializar ADIVINADO en falso Repetir mientras ADIVINADO sea falso

Preguntar por un número y almacenar en NUMERO Incrementar NUMERO_INTENTOS

Si NUMERO es igual a NUMERO_SECRETO, entonces hacer ADIVINADO verdadero Mostrar NUMERO_INTENTOS Fin

Page 41: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

41

En JAVA:

En este programa existe un contador de repeticiones, sin embargo, el bucle es controlado por la variable adivinado. Este tipo de variable es conocido como flag, dummy variable o centinela y pueden ser de cualquier tipo. En este caso utilizamos una variable de tipo boolean.

Completemos un poco el programa para que el bucle pare también si el usuario ingresa un 0. El programa debe dar los mensajes pertinentes:

Page 42: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

42

En este caso existen dos centinelas, la variable adivinado y el valor ingresado. Tener especial cuidado que el valor para el centinela no pueda ser confundido con un valor permitido y real del programa. Por ejemplo, si queremos que el bucle pare si se ingresa el 0, entonces el número secreto no puede ser 0.

Ejercicio:

4.8 , 4.9 y 4.10 del libro Java Como Programar 5ta Edición, Deitel.

Los ejemplos muestran una técnica para desarrollar algoritmos llamada mejoramiento de arriba a bajo (enfoque top-down).

3.4 Ejemplos desarrollados I

3.4.1 Factorial Escribir un programa que pida un número entero positivo al usuario y muestre el factorial.

Solución:

Page 43: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

43

Primero hacemos que el programa pida un número al usuario. Luego en un ciclo for, recorremos todos los números desde el número ingresado hsta 1 y vamos acumulando la multiplicación. Notar como se utiliza un incremento negativo.

¿Que ocurre si ingresamos el 18? En este caso queda claro que ha ocurrido overflow ya que arroja un número negativo. Pero tengamos cuidado, ¿Cuál es el mayor número entero positivo del cual podemos calcular el factorial usando variables de tipo int? Sabemos que el máximo entero representable con int es 2.147.483.647 y al ingresar el 12 obtenemos 479.001.600. Por lo tanto el factorial del número 13 ya sobrepasa el máximo entero. Modifique el programa para que utilice long para almacenar el factorial.

3.4.2 Pedir un valor de entrada hasta que sea válido Tomando el ejemplo anterior, modificar el programa para que pida el número tantas veces como sea necesario hasta que el usuario ingrese un valor entre 1 y 15.

Solución:

Antes de calcular el factorial, ponemos un ciclo que repita la acción de pedir el número mientras éste sea menor que 1 o mayor que 15. Se ha utilizado el operador lógico O (OR, '||')

Page 44: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

44

3.4.3 Cálculo de la raiz cuadrada por aproximación Construir un programa que calcule la raiz cuadrada de un número positivo cualquiera ingresado por el usuario. No se puede utilizar ninguna función que haga el cálculo.

Solución:

Una forma de encontrar la raiz de un número es por aproximación. La técnica consiste partir del número 1 e incrementar en pequeñas fracciones hasta que el cuadrado se apoxime lo suficiente al número ingresado. Definamos las siguientes variables:

numero: el número ingresado por el usuario al cual buscaremos la raiz cuadrada

maximo_error: máxima diferencia permitido entre el cuadrado de la posible raiz y el número. Si la diferencia entre estos dos valores es menor que máximo_error, la raiz se considera encontrada.

incremento: valor del incremento, debe ser suficientemente pequeño.

raiz: parte con el valor 1 y se incrementa

3.4.4 Comprobar si un número es primo Construya un programa que calcule si un número ingresado por el usuario es primo.

Solución:

Para comprobar si un número es primo debemos recorrer todos sus posibles factores. Si no existen más que dos, la unidad y el mismo número, entonces se considera primo. Los pasos son:

1. Pedir el número al usuario 2. Inicializar una variable boolean esprimo en verdadero. 3. Poner un ciclo for que parta su contador en 2 y repita mientras el contador

sea menor que el número. a. En cada paso, calcular el resto de la división del número por el

contador del ciclo. Si el resto es cero, cambiar esprimo a falso.

Page 45: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

45

4. Mostrar mensaje dependiendo de la variable esprimo.

Existen algunas consideraciones importantes con este programa:

a. Sería deseable verificar que el número ingresado sea mayor que 1. Para esto podemos utilizar parte del código del ejemplo 3.4.2.

b. En algunas definiciones, el 1 no se considera primo. ¿Qué pasa en este programa si se ingresa el número 1? ¿qué habría que hacer para que el 1 no se considerar primo?

c. El ciclo recorre todos los números desde el 2 hasta uno antes del número ingresado. Sin embargo, al encontrar el primer factor no necesita buscar otros para asumir que el número no es primo. Por ejemplo si ingresamos el 80000002 se encuentra inmediatamente el factor 2, sin embargo se repite el ciclo 80 millones de veces.

d. En este tipo de programas puede ser deseable que su ejecución completa se repita hasta que el usuario decida no seguir.

Solución 2:

Se ha incluido la variable esprimo como centinela del ciclo, de esta forma solucionamos el problema del punto c. Además para solucionar el punto d, el programa se ha metido dentro de un ciclo while que repite todo el proceso hasta que el usuario ingresa un 0.

Page 46: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

46

Notar como el ciclo for para verificar si el número es primo o no está dentro de otro ciclo (While). Esto se conoce como anidación de ciclos: el ciclo for está anidado dentro del ciclo while. Otra vez es importantísimo mantener orden e indentación del código fuente.

3.5 Estructura de Selección Múltiple

Existe una estructura de control que facilita la bifurcación del flujo del programa en más de dos caminos. Suponga el sigueinte ejemplo: se desea construir un programa en que el usario ingrese un núnmero entre 1 y 12 y se muestre en pantalla el nombre del mes asociado.

Para resolver este programa utilizaríamos varias veces la estructura if, anidando bloques:

Page 47: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

47

Es obvio que el programa resulta innecesariamente complejo. Para facilitarlo, usaremos una estructura conocida como switch/case:

Page 48: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

48

La estructura switch/case puede leerse como evaluar (variable byte, char, short o int) en caso de que el valor sea [valor 1]: instrucción1; instrucción2; ... salir de la estructura

Page 49: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

49

en caso de que el valor sea [valor 1]: instrucción3; instrucción4; ... salir de la estructura en otro caso: instrucción5; instrucción6; ...

Observar la instrucción especial break. ¿Qué sucede con el programa si quitamos esta instrucción? La estructura switch/case funciona de manera que cuando uno de los valores coincide, se realizan todos los bloques siguientes, a menos que se incluya break.

El caso por defecto (default) es opcional.

El diagrama de actividad para el ejemplo de los meses:

Page 50: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

50

3.6 Instrucciones break y continue

Las instrucciones break y continue permiten también controlar el flujo del programa. La instrucción break permite salir inmediatamente de un ciclo (while, for, do-while) o de un switch. La instrucción continue fuerza que se ejecute la siguiente vuelta del ciclo (while, for, do-while), saltándose las instrucciones siguientes dentro del bloque de repetición.

Los siguientes ejemplos muestran el uso del break y continue. El primer programa es una versión del programa para adivinar un número utilizando break. El segundo programa imprime todos los números entre el 1 y el 50 evitando los múltiplos de 4.

Page 51: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

51

3.7 Ejercicios

1) Escriba en pseudo código y construya el diagrama de actividad del segundo programa del ejemplo desarrollado 3.4.4.

2) Escriba un programa que muestre las tablas de multiplicar de los números 6, 7, 8 y 9 entre 5 y 12. Considere utilizar ciclos anidados. Desarróllelo primero en pseudo código y dibuje el diagrama de actividad.

3) Modifique el programa Secreto2 (de las sección 3.3.2) para que muestre "Felicitaciones, Ud. ha adivinado en el primer intento" en caso que se de esa situación. Dibuje el diagrama de actividad.

4) Construya un programa que muestre una cadena ingresada por el usuario de la siguiente forma: en la primera línea muestre sólo el primer carácter de la cadena, en la segunda línea muestre los dos primeros caracteres de la cadena, ... y así hasta escribir la cadena completa. Por ejemplo, si la cadena es "Hola a Todos", debe mostrar

H Ho Hol Hola Hola Hola a Hola a Hola a T Hola a To Hola a Tod Hola a Todo Hola a Todos

5) Construya un programa que pida al usuario dos enteros positivos y busque el mínimo común múltiplo entre ellos.

6) Construya un programa que pida al usuario dos enteros positivos y busque el máximo común divisor entre ellos.

Page 52: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

52

Capítulo 4 Programas modulares con métodos Los ejemplos desarrollados en este capítulo evidencian la necesidad de modularizar nuestras rutinas de código de modo de hacer más legibles nuestros programas y poder utilizar más de una vez las funcionalidades sin tener que escribirlas de nuevo. Por ejemplo: ¿no sería útil tener implementada una rutina para pedir un número al usuario hasta que éste ingrese uno válido (estableciendo el rango de números deseables)?, o, si quisiéramos imprimir los 10 primeros números primos, ¿no sería útil tener una función que nos indique verdadero o falso dependiendo si un número es o no primo?

4.1 Módulos

A medida que los programas crecen en complejidad y tamaño se hace necesario implementarlos por partes. Esto significa dividir el trabajo en módulos que podamos codificar de manera relativamente independiente. De esta forma el flujo del programa pasa de un módulo a otro.

Veamos un ejemplo: se quiere implementar un programa que imprima los primeros 10 números primos. En pseudo código: 1. Inicializar contador_primos en 0 2. Inicializar N en 2 3. Mientras contador_primos sea menor o igual a 10 hacer

a. Inicializar una variable boolean esprimo en verdadero. b. Poner un ciclo for que parta contador en 2 y repita mientras el contador

sea menor que N. i. En cada paso, calcular el resto de la división de N por el contador

del ciclo. Si el resto es cero, cambiar esprimo a falso. c. Si esprimo es verdadero

i. imprimir N ii. incrementar contador_primos en uno

Notar como el algoritmo para reconocer que un número es primo queda anidado dentro de otro ciclo. Ahora, si tuvieramos un módulo para verificar que un número es primo, digamos esPrimo(N), el programa se vuelve más sencillo: 1. Inicializar contador_primos en 0 2. Inicializar N en 2 3. Mientras contador_primos sea menor o igual a 10 hacer

a. Si esPrimo(N) es verdadero i. imprimir el número ii. incrementar contador en uno

El módulo esPrimo(N)se puede definir separadamente: 1. Inicializar una variable boolean esprimo en verdadero. 2. Poner un ciclo for que parta contador en 2 y repita mientras el contador sea

menor que N. a. En cada paso, calcular el resto de la división de N por el contador

del ciclo. Si el resto es cero, cambiar esprimo a falso. 3. devolver esprimo

Page 53: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

53

4.2 Módulos en JAVA: clases y métodos

En JAVA, la modularización existe de dos maneras: métodos y clases. Una clase es siempre la estructura modular por excelencia; los métodos (llamados procedimientos, funciones o subrutinas en otros lenguajes) siempre se declaran e implementan dentro de una clase.

Cuando desarrollamos un programa en JAVA, combinamos método y clases existentes con métodos y clases que nosotros mismos definimos. JAVA dispone de un amplio repositorio de clases y métodos ya implementados en la Interfaz de Programación de Aplicaciones, API (Application Programming Interface). Los métodos siempre están definidos dentro de alguna clase y las clases se agrupan y organizan en paquetes. Por ejemplo, cuando hacemos

import javax.swing.JOptionPane;

estamos "importando" a nuestra clase la clase JOptionPane que está en el paquete swing, que a su vez está en el paquete javax.

Veamos el ejemplo presentado anteriormente (en pseudocódigo) en JAVA:

Nuestra clase, llamada Primos, tiene dos métodos: main y esPrimo. El método main es el programa principal: cualquier clase que tenga un método main podrá ser ejecutada como un programa. En realidad, cuando ejecutamos un programa JAVA previamente compilado, el intérprete busca un

Page 54: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

54

método main; si no existe arroja un error. El método esPrimo sólo se ejecutará si se invoca dentro del método main, o dentro de otro método quesea invocado por el método main.

Analizando el método esPrimo podemos observar que para realizar su tarea requiere un número, del cual verificará su condición de número primo, y como resultado del proceso contestará verdadero o falso. En general, a un método ingresa información (materia prima de entrada) y sale información resultado del proceso:

El método esPrimo tiene como entrada un número entero (int) y devuelve un valor boolean (true, false).

En general un método podemos verlo de la siguiente manera:

Es evidente que un diagrama como el anterior que representa un método o función se parece a la figura de un programa como procesamiento de información (Capítulo 1): un método es un subprograma o subrutina y tiene prácticamente las mismas características que un programa completo.

4.3 Estructura de un método

En JAVA los métodos se definen de la siguiente manera:

A saber:

• La primera línea se denomina declaración del método e indica todo lo necesario para utilizar el método.

Page 55: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

55

• La palabra reservada public indica que el método es de acceso público. Esto significa que eventualmente podría ser utilizado desde otros programas.

• La palabra reservada static indica que el método está definido dentro del contexto estático de ejecución, y no se ejecutará desde el contexto de un objeto (veremos estos conceptos con detalle más adelante).

• El tipo de salida del método puede ser de cualquier tipo primitivo (int, char, byte, boolean, long, double, etc.) o de algún tipo definido como una Clase (por ejemplo String). Si deseamos escribir un método que no tenga datos de salida, especificamos void como tipo.

• La lista de parámetros es una lista de identificadores con sus tipos asociados separados por coma. Si un método no tiene parámetros de entrada se especifica con la lista vacía (pero se mantienen los paréntesis).

• El flujo del método debe llevar siempre a una instrucción return, la cual genera la salida del método. El valor que "retorna" o devuelve debe coincidir en tipo con el tipo de salida definido en la primera línea del método (declaración del método).

Por ahora crearemos métodos en el contexto estático de ejecución (el programa principal) y los declararemos públicos. Más adelante, cuando nos sumerjamos en los temas de la orientación a objeto descubriremos que significan estas características. Además, por ahora sólo utilizaremos valores de salido y parámetros de entrada de tipos primitivos y String.

Observación:

Por convención los nombres de los métodos se escriben con minúsculas excepto las primeras letras de las siguientes palabras que componen el nombre. Por ejemplo: sumar, sumarEnteros, calcularPromedioPonderado, etc.

Los nombres de las clases son con minúsculas excepto las primeras letras de todas las palabras que componen el nombre. Ejemplo: Automovil, NumeroComplejo, String, JOptionPane, etc.

Page 56: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

56

4.4 Ejemplos desarrollados

4.4.1 Conversor decimal a binario Se desea construir un programa para convertir números decimales a binarios. El programa debe pedir al usuario un número entero entre 0 y 255, validando el rango, y luego mostrar el valor en binario.

Solución:

Implementaremos los siguientes módulos:

int pedirEntero(int min, int max, String msg) : pide al usuario que ingrese un número hasta que ingrese un entero que esté entre min y max. La cadena msg nos permitirá decirle al método que mensaje mostrar al usuario. Como este método es de propósito general, lo implementaremos en una clase separada que llamaremos EntradaSalida (en un archivo EntradaSalida.java). Más adelante completaremos esta clase con una serie de métodos útiles para entrada y salida de información.

String convertir(int numero) : devuelve una cadena con la representación binaria (1s y 0s) del número entero de entrada.

El programa será: Inicializar num = pedirEntero(0, 255) Inicializar binario = convertir(num) Mostrar binario al usuario

La clase EntradaSalida

Page 57: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

57

4.4.2 Suma de binarios Se desea construir un programa para sumar dos números binarios de 8 dígitos. El programa preguntará por los valores en binario y mostrará la suma en binario. Si existe overflow deberá indicarlo (si la suma excede el valor 255 decimal).

Solución:

Para solucionar este problema implementaremos un método para pedir un binario de 8 cifras y un método para convertir cifras binarias a decimal. Luego sumaremos los valores como decimales y convertiremos el valor decimal de la suma en binario. Para esto último aprovecharemos el método implementado en el ejemplo anterior.

El programa SumaBinarios:

Page 58: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

58

Hemos agregado el siguiente método a la clase EntradaSalida:

El método pedirBinario pide una cadena al usuario hasta que éste ingresa una de largo 8 y compuesta sólo por caracteres 1s y/o 0s.

Page 59: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

59

4.4.3 Palíndromo

Un palíndromo es una frase que dice exactamente lo mismo si se lee de izquierda a derecha y de derecha a izquierda. Eso si, obviando la posición de los espacios en blanco, caracteres especiales distintos de letras y la diferencia entre mayúsculas, minúsculas y letras acentuadas.

Algunos palíndromos:

Yo soy Somos o no somos Anita lava la tina

Adán no cede con Eva, y Yavé no cede con nada Sé verla alrevés

Yo dono rosas, oro no doy ¿Acaso hubo búhos acá?

Dábale arroz a la zorra el abad.

Se desea construir un programa que verifique si un texto ingresado por el usuario es o no palíndromo.

Solución:

Pongamos atención a la definición de palíndromo: un texto que es igual de izquierda a derecha y de derecha a izquierda, si obviamos caracteres distintos de letras. Por lo tanto hagamos lo siguiente:

1. Pedir un texto al usuario 2. Quitar todos los caracteres distintos de letras, letras acentuadas y

espacios en blanco 3. Transformar a mayúsculas o a minúsculas 4. Crear una copia de la cadena invertida 5. Comparar la cadena con la invertida

En un enfoque modular, crearemos los siguientes métodos:

boolean esPalindromo(String frase): devuelve true si la frase es palíndromo. Este método implementa las acciones 2, 3, 4 y 5 listadas anteriormente.

String filtrarSoloLetras(String frase): devuelve una cadena que es la cadena frase de entrada quitando todos los caracteres distintos de letras.

String invertir(String cadena): devuelve la cadena invertida.

Creamos entonces la clase Palindromo con los métodos indicados y un método main que ejecute el programa:

Page 60: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

60

4.5 Bibliotecas de funciones

Muchos de los métodos construidos en los ejemplos desarrollados anteriormente podrían utilizarse en otros programas. Algunos son de propósito general y bastan útiles para la mayoría de los programas que construyamos. Cuando un programador se encuentra en este tipo de casos puede construir una biblioteca o librería de funciones. En JAVA, una biblioteca de funciones será una clase con métodos estáticos.

Un ejemplo de biblioteca de funciones es la clase EntradaSalida, creada en el ejemplo 4.4.1. Existen bibliotecas de funciones en la API de JAVA como la clase Math (java.lang.Math) la cual contiene métodos que implementan funciones numéricas como potencia, raíz, valor absoluto, etc.

Como ejercicio, definiremos una clase ConversionBases, una biblioteca de funciones para convertir entre bases numéricas con los métodos:

int binarioADecimal(String bin) int hexadecimalADecimal(String hexadecimal) String decimalABinario(int dec) String decimalAHexadecimal(int dec)

Page 61: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

61

String binarioAHexadecimal(String bin)

Aprovechando la definición de la clase ConversionBases, mostramos a continuación el diagrama de clases UML asociado:

Los diagramas de clases permiten definir clases y sus métodos sin escribir los algoritmos que estos incluyen. Utilizaremos este tipo de diagramas en el siguiente capítulo.

Page 62: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

62

4.6 Ejercicios

1. Tomando como base el método PedirEntero, construya un método pedirReal para pedir al usuario un valor numérico real hasta que sea válido. El método debe recibir el rango de números válidos y debe devolver un double.

2. Construya un método para verificar si un número es par. Debe recibir como entrada un entero y devolver true o false (boolean).

3. Construya un método para calcular el factorial de un número entero positivo.

4. Usando los métodos de los dos ejercicios anteriores, reescriba el programa de la sección 3.4.2.

5. Escriba un programa que pida al usuario tres números enteros: día, mes y año y muestre la fecha en formato dd de mes de aaaa. Por ejemplo: si el usuario ingresa 12, 6, 2004 para día, mes y año respectivamente, el programa debe mostrar: 12 de Junio de 2004. Si los valores son erróneos (la fecha no se puede representar) el programa debe arrojar "La fecha no es válida". Construya el programa implementando primero los siguientes métodos:

a. boolean validarMes(int mes): devuelve verdadero si mes está entre 1 y 12.

b. String nombreMes(int mes): devuelve el nombre del mes.

c. boolean validarAgno(int agno): devuelve verdadero si agno está entre 1950 y 2007.

d. boolean validarDia(int dia, int mes, int agno): devuelve verdadero si la fecha es válida. Para comprobar esto tener en cuenta que:

i. Los meses 1, 3, 5, 7, 8, 10 y 12 tienen 31 días.

ii. Los meses 4, 6, 9 y 11 tienen 30 días.

iii. El mes 2 (febrero) tiene 28 días, excepto los años bisiestos en que tiene 29.

iv. Un año bisisesto es un año divisible por 4. No se consideran bisiestos los años divisibles por 100 a menos que sean divisibles además por 400.

6. Construya un método que muestre las primeras 100 cifras de la serie de Fibonacci. Cada cifra de esta serie se calcula sumando las dos cifras anteriores. Por ejemplo, los primeros 10 elementos de la serie:

1 1 2 3 5 8 13 21 34 55

Page 63: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

63

Capítulo 5 Arreglos [parte 1]

Generalmente es necesario que un programa procese gran cantidad de información, y en estos casos requerimos estructuras de datos que lo permitan. Por ejemplo: supongamos un programa que maneja las notas de alumnos de un curso y que permite agregar, eliminar y modificar notas, calcular los promedios por alumno, calcular los promedios generales, etc. En otras palabras: permite administrar listas con notas para cada alumno. Podemos crear listas de datos usando arreglos:

5.1 Crear arreglos

La siguiente instrucción declara un arreglo de enteros, referenciado por la variable arreglo1.

int[] arreglo1;

La instrucción es sólo declarativa, lo que significa que se ha creado la referencia arreglo1, pero no se ha reservado espacio en memoria para la lista de enteros. Para contruir el arreglo debemos especificar el tamaño de éste, es decir, cuántos elementos podrá contener:

arreglo1 = new int[20];

En este caso se ha definido que el arreglo arreglo1 tiene una capacidad de 20 elementos.

La declaración y la cosntrucción del arreglo son procesos distintos, pero pueden resumirse a una sola línea. Las siguientes dos instrucciones son válidas y crean arreglos (notar como no importa que los paréntesis cuadrados estén luego del tipo o luego del nombre de la variable):

int otroarreglo[] = new int[100];

int[] numeros = new int[7];

int [] numeros = new int[7];

tipo

esarreglo

nombrecrea el espacio

en memoria

tamaño

Las siguientes instrucciones crean arreglos de otros tipos:

double[] reales = new double[1000];

float[] fnumeros = new float[30];

char[] simbolos = new char[256];

boolean[] flags = new boolean[8];

Page 64: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

64

5.2 Acceder a los elementos de un arreglo

Ahora bien, ¿cómo modificamos y accedemos a los elementos del arreglo? La siguiente instrucción establece el valor del primer elemento del arreglo en 10:

numeros[0] = 132;

numeros[6] = -32

Los elementos de un arreglo se almacenan en forma secuencial y se identifican por una posición dentro del arreglo. El primer elemento está en la posición 0.

132 0 0 0 0 0 -32numeros[0] numeros[1] numeros[2] numeros[3] numeros[4] numeros[5] numeros[6]

numeros

Notar que si un arreglo tiene N elementos, el último está en la posición N-1.

5.3 Recorrer un arreglo

Una de las tareas básicas habituales en el procesamiento de arreglos es recorrerlos total o parcialmente. El siguiente programa crea el arreglo int[] numeros, establece algunos valores y los imprime en pantalla recorriéndolo con una estructura cíclica. Notar que para controlar el ciclo se ha utilizado la propiedad length del arreglo (en inglés: longitud o largo):

Podemos obtener el largo de un arreglo mediante la propiedad length, lo cual es recomendable, aunque el tamaño del arreglo se defina dentro del programa. La propiedad length es siempre un número entero:

int largo1 = reales.length;

int largo2 = fnumeros.length;

int largo3 = simbolos.length;

int largo4 = flags.length;

Crear e inicializar arreglos, operador { }

Page 65: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

65

En Java es posible declarar, crear y rellenar un arreglo en una sola instrucción, especificando los valores del arreglo entre paréntesis de llaves ( '{' ,'}'):

int [] nums1 = {11,12,-4,43,9,3,5,6,0,-2,4,7};

int [] nums2 = {1,-3,0,2,-1,5,23,7,-21,-2,6};

Este tipo de instrucciónes será de utilizad para contruir algunos programas con arreglos sin preocuparnos de hacer que los valores de los elementos sean adquiridos por el programa de una fuente externa (usuario, archivo, base de datos, conexión de red, etc.) y centrándonos en el manejo de arreglos (aunque por lo general no es el caso).

5.4 Programas de ejemplo

El siguiente programa genera tres arreglos, dos de ellos con valores definidos a priori, y el tercero contendrá la intersección (los elementos repetidos) de los otros dos:

El siguiente programa transforma un arreglo de caracteres, pasando las letras a mayúsculas:

Page 66: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

66

5.5 Arreglos y métodos

Incorporaremos ahora los arreglos como entrada y/o salida de métodos; es decir, crearemos métodos que reciban como parámetros de entrada y/o devuelvan arreglos.

5.5.1 Arreglos como parámetros de entrada Un sencillo ejemplo muestra como un método int suma(int[] numeros) devuelve la suma de los elementos de un arreglo:

La siguiente clase muestra un programa que crea un arreglo de números reales que contiene las notas de un alumno, luego utiliza métodos para buscar la menor nota, la mayor nota y calcular el promedio.

Page 67: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

67

5.5.2 Arreglos como salida de un método El siguiente código muestra un método que devuelve un arreglo con los primeros n elementos de la serie de Fibonacci, donde n es un parámetro ingresado por el usuario.

Notar como el método verifica que n esté entre 1 y 20, de otra forma devuelve nulo (null). Notar además como el método crea un arreglo (línea 20) con el nombre de resp y finalmente devuelve esta referencia que es copiada por el programa (metodo main) en la variable serie.

Page 68: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

68

Por supuesto, pueden existir métodos que reciban y devuelvan arreglos. El siguiente ejemplo construye un arreglo de enteros con los valores de las longitudes de las cadenas contenidas en un arreglo de Strings.

Page 69: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

69

5.6 Ejemplos desarrollados

Operaciones con arreglos:

Existen una serie de operaciones básicas con arreglos que podemos implementar. Supongamos que se desea implementar una biblioteca de funciones para arreglos de tipo entero con los siguientes métodos:

int[] sumar(int[] vector, int escalar)

int[] sumar(int[] vector1, int[] vector2)

int[] multiplicar(int[] vector, int escalar)

int multiplicar(int[] vector1, int[] vector2)

int[] cortar(int[] vector, int cantidad)

int[] cortar(int[] vector, int limite1, int limite2)

int[] unir(int[] vector1, int[] vector2)

Solución:

Notar que existen dos métodos sumar y dos método multiplicar. El primer método sumar devuelve un arreglo como resultado de sumar cada elemento de vector y escalar. El segundo método sumar, en cambio, suma cada elemento de vector1 con su correspondiente en posición en el arreglo vector2. Es necesario considerar que si los arreglos vector1 y vector2 tiene distinto tamaño, se espera obtener un arreglo resultado del mismo largo que el mayor entre los dos arreglos, en donde se han sumado todos los elementos y se han conservado aquellos del arreglo más largo que no tienen par en el otro. De manera análoga, el primer método multiplicar multiplica cada elemento de vector por escalar, y el segundo método multiplicar, multiplica los vectores de manera matricial (considerando el

Page 70: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

70

primer arreglo como de dimensión 1xN y el segundo como de Nx1, el resultado es de 1x1, un escalar). En este último caso, los vectores deben ser del mismo tamaño, sinó debe devolver 0.

El primer método cortar, devuelve un arreglo con los primeros cantidad números de vector. El segundo, en cambio, obtiene todos los elementos entre la posición limite1 y limite2, ambas incluidas.

Page 71: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

71

Page 72: Apuntes_POO_Unidad_1_v0.3

Programación Orientada a Objetos

72

5.7 Ejercicios

1. Construya los métodos "minimo" y "maximo" que devuelvan el mayor valor contenido en un arreglo de números (double) pasado como parámetro.

2. Construya un método que normalice un arreglo de double a porcentajes del mayor número contenido.

3. Construya un método que normalice un arreglo de double para que todos los elementos sumados den siempre 1, manteniendo las proporciones.

4. Construya un método "promedio" que devuelva el promedio de un conjunto de valores pasados como un parámetro arreglo de double.

5. Construya un método "promedioPonderado" que reciba dos arreglos y calcule el promedio ponderando los elementos del primer arreglo con respecto al segundo arreglo. El método debe verificar que ambos arreglos tengan el mismo largo.

6. Construya un método "factores" que devuelva un arreglo de int con todos los factores de un número entero.

7. Construya un método "existe" que devuelva la posición de la primera ocurrencia de un número en un arreglo. Debe devolver -1 si el número no existe en el arreglo.

8. Construya un método "cuantasPalabras" que cuente el número de palabras en una cadena de caracteres pasada como parámetro.

9. Construya el método "separaCadena" que separe una cadena de caracteres en un arreglo con las palabras (delimitadas por espacio en blanco).