Apuntes Algoritmos y Programas

Page 1

ALGORITMOS Y PROGRAMAS Parte I: Cuaderno de Apuntes Oto単o 2014


Instituto Tecnológico Autónomo de México

1 Contenido 1.

Introducción _________________________________________________________ 5

2.

Conceptos básicos de programación orientada a objetos POO _________________ 6

3.

Conceptos básicos de Alice _____________________________________________ 8

4.

5.

3.1.

Ventana de Alice _______________________________________________________ 8

3.2.

Historias y guiones ______________________________________________________ 9

3.3.

Instanciar objetos en el mundo ___________________________________________ 10

3.4.

Métodos básicos predefinidos ____________________________________________ 10

3.5.

Codificación en Alice ___________________________________________________ 10

3.6.

Creación de nuevos métodos ____________________________________________ 11

3.7.

Uso de comentarios

3.8.

Movimiento de la cámara _______________________________________________ 12

3.9.

Posición______________________________________________________________ 13

3.10.

Sincronización ________________________________________________________ 14

3.11.

Variables _____________________________________________________________ 15

3.12.

Creación de nuevas funciones ____________________________________________ 16

______________________________________________ 12

Estructuras algorítmicas ______________________________________________ 18 4.1.

Algoritmo ____________________________________________________________ 18

4.2.

Diagramas de Flujo _____________________________________________________ 18

4.3.

Estructuras algorítmicas de selección ______________________________________ 19

4.4.

Estructuras algorítmicas de repetición _____________________________________ 20

Introducción a Java ____________________________ ¡Error! Marcador no definido. 5.1.

Estructura básica de un programa _________________________________________ 24

5.2.

Sintaxis básica ________________________________________________________ 24

5.3.

Tipos primitivos y referencias ____________________________________________ 24

5.4.

Expresiones, operadores y prioridad de operadores __________________________ 25

5.5.

Variables y constantes __________________________________________________ 26

5.6.

Uso de comentarios ____________________________________________________ 27

5.7.

Sintaxis de las estructuras de control ______________________________________ 28

5.8.

Clase Math ___________________________________________________________ 29

5.9.

Clase String ___________________________________________________________ 30

Apuntes Algoritmos y Programas

2


Instituto Tecnológico Autónomo de México

5.10.

Import _______________________________________________________________ 32

5.11.

Clase Scanner _________________________________________________________ 32

5.12.

Clase System __________________________________________________________ 33

5.13.

Instrucción Assert ______________________________________________________ 33

5.14.

Notas importantes _____________________________________________________ 34

6.

Representación de una clase en UML ____________________________________ 35

7.

Clases en Java_______________________________________________________ 37

8.

9.

7.1.

Definición de clase _____________________________________________________ 37

7.2.

Declaración de la clase __________________________________________________ 37

7.3.

Cuerpo de la clase _____________________________________________________ 39

7.4.

La Clase Object ________________________________________________________ 44

Modificadores de acceso en Java _______________________________________ 45 8.1.

Accesar a los Miembros de la Clase ________________________________________ 45

8.2.

Accesar a una Clase ____________________________________________________ 46

Manejo de Objetos en Java ____________________________________________ 47 9.1.

Crear Objetos _________________________________________________________ 47

9.2.

Declarar un Objeto _____________________________________________________ 47

9.3.

Instanciar un objeto ____________________________________________________ 47

9.4.

Inicializar un Objeto ____________________________________________________ 48

9.5.

Referenciar Variables de un Objeto _______________________________________ 48

9.6.

Llamar a Métodos de un Objeto __________________________________________ 48

9.7.

Eliminar Objetos no Utilizados ___________________________________________ 48

9.8.

Recolector de Basura ___________________________________________________ 49

9.9.

Finalizar _____________________________________________________________ 49

10. Subclases, Superclases, y Herencia ______________________________________ 50 10.1.

Crear Subclases________________________________________________________ 50

10.2.

Sobrescribir Métodos ___________________________________________________ 51

11. Arreglos ___________________________________________________________ 52 11.1.

Características, declaración e instanciación _________________________________ 52

11.2.

Asignación de un valor a una posición específica del arreglo ___________________ 53

11.3.

Teniendo acceso a un elemento del arreglo _________________________________ 54

11.4.

Aumentar la capacidad de un arreglo ______________________________________ 54

11.5.

Corrimientos __________________________________________________________ 55

Apuntes Algoritmos y Programas

3


Instituto Tecnológico Autónomo de México

11.6.

Intercambio de elementos _______________________________________________ 56

11.7.

Ordenamiento por selección directa _______________________________________ 56

11.8.

Búsquedas en arreglos __________________________________________________ 57

11.9.

Uso de arreglos del tipo <T> _____________________________________________ 60

12. Arreglos con lectura de archivos ________________________________________ 62 13. Manejo de listas en Java con ArrayList ___________________________________ 66 14. Interfaces gráficas en Java ____________________________________________ 68 14.1.

Vista ________________________________________________________________ 68

14.2.

Controlador __________________________________________________________ 71

15. Ejecutar un programa en Java fuera de un IDE ____________________________ 75 16. Consulta de API’s en Java _____________________________________________ 78 17. Generación automática de documentación _______________________________ 80 Zoologico _________________________________________________________________________ getNombre ________________________________________________________________________ getDireccion _______________________________________________________________________ setUnAnimal _______________________________________________________________________ cuantosPorRaza ____________________________________________________________________ promEdades _______________________________________________________________________

Apuntes Algoritmos y Programas

82 82 83 83 83 83

4


Instituto Tecnológico Autónomo de México

1. Introducción Este cuaderno de apuntes tiene la finalidad de servir de guía al curso de Algoritmos y Programas, explicando de forma breve algunos de los temas tratados en el curso. Es importante resaltar que no pretende, en ningún momento, suplir las clases, si no ser una ayuda a las mismas. De igual forma se exhorta al alumno a hacer el mayor número posible de ejercicios de la materia, incluidos en el cuaderno de ejercicios, como complemento a la teoría aquí presentada.

Apuntes Algoritmos y Programas

5


Instituto Tecnológico Autónomo de México

2. Conceptos básicos de Programación Orientada a Objetos POO La programación orientada a objetos, es una forma de programar donde una aplicación se expresa como un conjunto de objetos, que colaboran entre sí para realizar tareas, se le denomina POO y se hizo popular en los años 90’s. Esta forma de programar permite hacer los programas y módulos más fáciles de escribir, mantener y reutilizar. Un objeto contiene toda la información que permite definirlo e identificarlo. A su vez, los objetos contienen métodos y funciones que definen su comportamiento y sus habilidades, es decir lo que pueden hacer. Toda esta información de los objetos se almacena en las Clases, que son lo que equivale al molde o a los planos. Para poder “construir” o instanciar los objetos, se toman los planos y se “hacen” los objetos, los cuales se van a distinguir entre ellos por los valores de sus atributos. Actualmente existen muchos lenguajes de programación que soportan la POO como Java o Alice, en los cuales se enfoca el curso. Los conceptos básicos de la POO son:  Clase: es la abstracción de un concepto de manera general. Define el tipo de datos (atributos) que guarda el objeto, así como su funcionalidad (métodos y/o funciones).  Objeto: es una instancia u ocurrencia de una clase. Guarda datos y proporciona métodos para llegar a ellos y modificarlos. Es una copia de la clase que tiene los mismos atributos (con valores propios) y sus métodos y/o funciones.  Atributos: son las características o propiedades específicas al objeto definidas en una clase.  Métodos: son las operaciones que pueden realizar los objetos de una clase.  Funciones: son métodos con la particularidad de que arrojan un (único) valor de un cierto tipo. Algunas características de la programación orientada a objetos:  Abstracción: es la característica esencial de las clases ya que sirve como un modelo para los objetos.  Herencia: define una relación entre clases, ayuda a organizar las clases jerárquicamente y permite, entre otras cosas, compartir atributos y métodos entre ellas. Clase base (súper clase) Conceptos generales 

Clase derivada (subclase) Conceptos específicos

Encapsulamiento: se utiliza para restringir el acceso a los atributos y/o métodos de una clase; se pueden definir distintos grados de acceso a los miembros de la clase: o private (-): sólo se puede usar y modificar por la misma clase.

Apuntes Algoritmos y Programas

6


Instituto Tecnológico Autónomo de México

o protected (#): se utiliza principalmente en herencia. Además de la súper clase, las subclases pueden tener acceso. o public (+): cualquier miembro de cualquier clase tiene acceso. Polimorfismo: es cuando comportamientos diferentes en objetos diferentes tienen el mismo nombre, al utilizar el nombre este actuará conforme a lo definido en cada objeto.

Apuntes Algoritmos y Programas

7


Instituto Tecnológico Autónomo de México

3. Conceptos básicos de Alice Alice es un programa educativo para enseñar a programar de forma fácil a través de animaciones en un ambiente 3D. Fue desarrollado por la Universidad de Carnegie Mellon como una herramienta gratuita para introducir a los alumnos en los conceptos de la programación orientada a objetos POO. Recordando que en POO un programa se expresa como un conjunto de objetos que colaboran entre ellos para realizar tareas, Alice tiene definida una serie de clases para utilizar objetos que ya tienen funcionalidad programada y a los cuales se les puede agregar más funcionalidades si así se requiere.

3.1.Ventana de inicio Cuando se inicia Alice se muestra la siguiente ventana:

Esta ventana contiene los siguientes menúes:  File: para manipular los mundos.  Edit: para las preferencias del código: debe tener Java Style in color, para poder relacionarlo mejor cuando se programe en Java.  Tools: para estadísticas.  Help: Tutoriales. En la parte superior muestra los siguientes botones:  Play: para correr el programa.  Undo: deshacer acciones.  Redo: rehacer acciones.  Basurero: para borrar cosas.

Apuntes Algoritmos y Programas

8


Instituto Tecnológico Autónomo de México

Debajo de estos botones, del lado izquierdo se muestra el árbol de Objetos: Es donde se muestra los objetos instanciados en el mundo (el mundo es un objeto). El mundo tiene tres objetos por default la cámara, la luz y el piso. Debajo del árbol de objetos está el Área de detalles, la cual tiene tres pestañas que muestran los atributos, métodos y funciones del objeto seleccionado en el árbol de objetos. Al centro se muestra un cuadro con el mundo que se va a trabajar y los objetos instanciados en él. A la derecha de la vista del mundo está el área de eventos: para decirle al programa qué hacer cuando ocurra cierto evento, por default cuando el mundo empieza se va a “myFirst method” del mundo. Debajo del área de eventos se encuentra el área de edición: es donde se escribe el programa. Por último, en la parte inferior de la ventana, se encuentran las sentencias de control para ayudarnos a programar. Los programas en Alice se resuelven a través de la animación, por lo que hacer un programa o proyecto en Alice lo podemos comparar con hacer una película. Para esto primero hay que definir la historia a contar, quienes son los protagonistas (objetos), en donde están (mundo) y que hacen (acciones), ya que Alice trabaja con programación orientada a objetos. Para crear un proyecto se debe de conocer entonces, la estructura básica de lo que se quiere realizar. Hay que empezar escribiendo la historia, y si es muy larga hay que saber cuáles son las escenas que se van a realizar, en cuántos “shots” y el ángulo de la cámara en cada una de ellas.

3.2.Historias y guiones Una historia de usuario se utiliza para describir lo que un usuario debe ver cuando se ejecute un programa. Es decir, como si fuese el libreto de la película. Esta historia de usuario debe indicar los sujetos (objetos) que interactúan, el mundo donde interactúan y también los elementos de fondo (objetos escenográficos). Por último se deben especificar las acciones a realizar por cada uno de los objetos y la secuencia de las mismas. Los guiones gráficos, “storyboards” o sketches son dibujos de lo que realizará el programa que se diseñó. Cada uno se utilizará para mostrar cambios en la pantalla. Los sketches también proporcionan tres cosas importantes acerca de los objetos que se verán en la pantalla:  Posición: dónde está un objeto respecto a otros.  “Pose”: da información acerca de la ubicación de las partes del objeto (si las tiene).  Orientación: hacia qué dirección está volteando. Ya que se tiene definida la historia, es decir se ha definido la historia de usuario y se tienen una serie de guiones gráficos que ejemplifiquen lo que queremos hacer, hay que revisar que Alice tenga los objetos necesarios y que éstos posean la funcionalidad necesaria (métodos o funciones) para realizar las actividades requeridas en la historia, en caso de que no los tenga Alice nos permite crear cierto tipo de objetos y añadirles funcionalidad a todos.

Apuntes Algoritmos y Programas

9


Instituto Tecnológico Autónomo de México

3.3.Objetos en el mundo Para instanciar objetos en el mundo se presiona el botón de “Add Objetcs” para que Alice nos muestre la galería de clases con las que cuenta y buscamos con la que deseamos trabajar. Se elige una, se da doble clic, se instancia el objeto en el mundo y se presiona el botón de “Done”. Se deben instanciar todos los objetos necesarios en la historia definida.

3.4.Métodos básicos predefinidos Todos los objetos de Alice tienen una serie de métodos y funciones ya definidos, es decir, “ya saben” hacer ciertas actividades. Los métodos y funciones predefinidos los podemos ver en el área de detalles, previa selección de cada objeto que ha sido “dibujado” (instanciado) en el mundo. La diferencia principal entre un método y una función es que las funciones regresan un valor y los métodos no, ambos pueden tener o no parámetros, que son lo que se necesitan especificar para que el objeto realice la acción deseada. Estos métodos y funciones, en conjunto con las instrucciones doInOrder y doTogether, permiten realizar las animaciones. Para ver los métodos de los objetos, siempre se deben seleccionar, primero el objeto a revisar en el mundo o en el árbol de objetos y se debe dar clic en la pestaña “methods” en el área de detalles.

3.5.Codificación Una vez establecidos los objetos y sus actividades, hay que pasar la historia a código en el área de edición, en esta área siempre aparece “my first method” por default. 3.5.1. My first method El el método con el que inicia la ejecución del programa, es el lugar donde se escriben las acciones que se realizarán en nuestra película. El programa, siempre ejecuta este método antes que cualquier otro (a menos que se indique lo contrario en el área de eventos) por lo que a partir de aquí se deben hacer los llamados a los demás métodos de nuestros objetos. 3.5.2. Instrucciones de control: doInOrder y doTogether La instrucción “DoInOrder” es una estructura secuencial en la cual se pueden escribir llamados a métodos, hará que dichos métodos se realicen en el orden en que aparecen, uno a la vez y de arriba hacia abajo en orden secuencial.

Apuntes Algoritmos y Programas

10


Instituto Tecnológico Autónomo de México

En este caso Alice se mueve 0.5 m hacia delante y depues dice “Hello”.

La instrucción “DoTogether” permite que dos métodos se realicen simultáneamente por uno o más objetos. En este caso Alice se mueve 0.5 m hacia delante y al mismo tiempo dice “Hello”.

3.6.Creación de nuevos métodos Si al revisar la funcionalidad de un objeto vemos que no tiene un método o función con la que pueda realizar la actividad requerida en nuestra historia, se lo podemos programar. Para crear un nuevo método se tiene que seleccionar el objeto en el árbol de objetos que se le desee agregar el método y seleccionar la pestaña de “methods” en el área de detalles. Luego se debe dar clic al botón “create new method” y después nombrar el nuevo método. También se pueden crear métodos en el mundo por ser un objeto (estos métodos se utilizan principalmente para escenas de la película con el objetivo de hacer módulos y dividir en partes la gran película).

En la pestaña que se crea con el nuevo nombre de método (en este caso miMetodo) se deben escribir las acciones. Conviene que los nombres de métodos contengan verbos que describan la acción que se desea llevar al cabo (corre, vuela, camina, marcha, saluda, etc.) y que comiencen con minúscula. Para probar que el método tenga la funcionalidad deseada, es necesario invocarlo desde “World.myfirstmethod” (por ejemplo Alice.miMetodo()). Para lo anterior se tiene que insertar en “my first method” una instrucción doInOrder o doTogether (en versiones menores a Alice 2.0) y después, desde el árbol de métodos del objeto se arrastra el método que se acaba de crear.

Apuntes Algoritmos y Programas

11


Instituto Tecnológico Autónomo de México

Como ya se mencionó, se pueden crear otras “escenas” al establecer un método nuevo que pertenezca al objeto mundo. La diferencia es que el método se tiene que crear en el mundo y normalmente, se le da el nombre de escena y el número con que se le desee identificar o un nombre descriptivo de la escena que se implementará (tomaDelCastillo, atqueInicial, saludo, despedida, escena1, etc.), de esta manera se hace modular (se divide en segmentos) nuestro programa y se hace más sencillo, ya que se ataca el problema por partes y es más fácil su revisión. También se recomienda que al presentarse un método muy largo (más de una pantalla de código) dentro de la escena se divida en dos o más partes, con esto se pretende disminuir el número de errores. A estas divisiones se les llama “shots”. El procedimiento para crearlos es el mismo que al principio de la sección y se recomienda que el nombre de cada “shot” tenga el mismo nombre del método que lo va a llamar y que sigan un orden (por ejemplo: el método world.playScene2 se dividirá en world.playScene2Shot1 y world.playScene2Shot2). El método world.playScene2 deberá llamar a estos dos nuevos métodos con un doInOrder, ya que ese es el propósito de la división.

3.7.Comentarios Los comentarios se utilizan para indicar que hace un programa, quien creó el programa, cuándo fue hecho y para poner notas explicativas o aclaratorias en el código. Esta etiqueta es muy útil ya que muchas veces las personas que leen un programa podrían no saber el propósito de cada uno de los métodos y descubrirlo puede llevar mucho tiempo. Por lo que es conveniente siempre poner en myFirstMethod un comentario con el nombre del autor, fecha y propósito general del programa, para documentarlos correctamente. Para insertar comentarios en Alice, se debe arrastrar desde abajo el control de comentarios (un símbolo denotado por //) hasta que se encuentre justo arriba del método que se desea explicar o la parte de código que se desea aclarar y se escribe la explicación.

3.8.Movimiento de la cámara Como la cámara en Alice también es un objeto, varios métodos se pueden utilizar para moverla, pero muchas veces el hecho de mover la cámara es complicado, sobre todo cuando se quiere regresar a posiciones anteriores. Para facilitar esto existen los dummies. Lo primero que hay que hacer es saber dónde se va a ubicar la cámara en un momento específico y después hacer que se mueva hacia ese lugar (moviendo los controles de flecha en la parte baja de la ventana del mundo), ya que se encuentra en la posición y orientación adecuadas, se creará el dummy. Para crear el dummy, en la ventana del mundo se presiona el botón “Add objects”, se selecciona el botón “more controls” y posteriormente el que dice “drop dummy at camera”. Este nuevo dummy creado, que es un objeto (al cual se le puede cambiar el nombre para saber a cuál se hace referencia en caso de que haya más de uno) es sólo un Apuntes Algoritmos y Programas

12


Instituto Tecnológico Autónomo de México

marcador invisible, un señuelo, pero tiene la misma posición y orientación (punto de vista) de la cámara previamente escogidas.

Si hubiera otra posición y orientación deseada, se deberá mover la vista (nuevamente con las flechas en la ventana) y se puede crear otro dummy repitiendo los mismos pasos de antes. Por lo tanto, en lugar de mover la cámara sólo se va a mover el punto de vista. Se recomienda que si se va a estar moviendo el punto de vista del mundo con los dummies, se cree al inicio un dummie con la vista original para poder regresar a ella cuando se necesite. Una vez creados los dummies (cuantos sean necesarios) se tiene que buscar el método que va a usarlos. Se tiene que arrastrar una instrucción doInOrder y en el árbol de objetos dar clic a “camera” y luego a la opción setPointOfView() para que sea lo primero que se realice en el método; hay que seleccionar como parámetro el dummy adecuado. Una vez hecho esto, se debe de fijar la duración en cero para que la cámara se mueva a la ubicación del dummy instantáneamente.

3.9.Posición Para cambiar la posición de un objeto en Alice, existe el método move(). Hay 6 tipos de movimientos que puede realizar el objeto: forward, backward, left, right, up y down. Un cambio en la posición del objeto se realiza respecto a los ejes del mundo.

3.9.1. Orientación (turn, yaw, pitch, roll) Todos los objetos en Alice (recuerda que las partes de un objeto a su vez son objetos) tienen 3 ejes (por estar en 3D): derecha-izquierda (eje X), arriba-abajo (eje Y) y adelanteatrás (eje Z), considera también que tienen un punto pivote para hacer los cambios, este punto varia de objeto a objeto (cada parte de un objeto tiene su propia orientación y punto pivote) y es de acuerdo a su orientación del momento, es decir, cuando se cambia la orientación de un objeto, los ejes también cambian, por lo que si después de haber cambiado la orientación del objeto también se quiere cambiar su posición, entonces ésta cambiará respecto a los “nuevos” ejes. Los tres ejes son la dirección (heading o yaw), la elevación (pitch) y el ángulo de rotación (roll). Apuntes Algoritmos y Programas

13


Instituto Tecnológico Autónomo de México

Yaw: es el cambio de orientación sobre el eje derecha-izquierda. Este cambio se realiza usando la instrucción turn(LEFT,…) o turn(RIGHT,…). Por ejemplo, al negar con la cabeza.

Pitch: es el cambio de orientación sobre el eje arriba-abajo, es decir. Este cambio se realiza usando la instrucción turn(FORWARD) o turn(BACKWARD). Por ejemplo, al asentir con la cabeza.

Roll: es el cambio de orientación, como una rotación, sobre el punto pivote. Este cambio se realiza usando la instrucción roll(LEFT,…) o roll(RIGHT,…).

Para conocer bien los movimientos de los objetos en Alice, practica con los cambios de posición para que identifiques claramente sus movimientos de acuerdo a su orientación.

3.10.

Sincronización

A veces es necesario que dos o más objetos se muevan juntos, para esto se puede usar la instrucción “doTogether”, pero existe una manera más sencilla usando la llamada “vehicle property”, “vehicle” es un atributo de cada objeto que por default tiene asignado el mundo. Por ejemplo, si se quiere que una niña cabalgue un caballo, o que la niña navegue en un bote, lo único que se tiene que hacer es cambiar el “vehicle” de la niña del mundo al caballo o al bote según sea el caso. Para hacer esto se puede hacer desde un inicio seleccionando el objeto en el mundo y en el árbol de detalles en la pestaña de Apuntes Algoritmos y Programas

14


Instituto Tecnológico Autónomo de México

“properties” se selecciona “vehicle” y se elige el objeto que queremos sea el vehículo. La otra manera es en tiempo de ejecución, cuando no queremos que en todo el programa el vehículo sea el mismo y se usa la siguiente expresión: objeto.set(vechicle, elObjetoQueServiráDeVehicle). Para el primer ejemplo sería: niña.set(vehicle, caballo) ocasionando que si se aplica un método move() al caballo, la niña se mueva también sincronizando sus movimientos.

3.11.

Variables

Una variable es un espacio de memoria reservado para almacenar valores temporalmente en la computadora, todas las variables se deben declarar especificando un nombre y el tipo de dato a almacenar. De acuerdo al lugar donde se declaren tienen distinto alcance. 3.11.1. Variable de método Se crean dentro de un método en Alice con el botón “create a new variable” y es necesario definir su nombre (normalmente debe describir lo que almacena), tipo y valor inicial. También llamadas variables locales porque sólo se puede acceder a ellas desde el método en que se definieron. Estas variables son usadas principalmente cuando:  Se calculan y guardan valores que se usarán más de una vez dentro del método.  Se requiere guardar valores que el usuario provee, es decir cuando necesitamos que el usuario dé un valor para poder trabajar en el programa, SOLO en los métodos del mundo o escenas, ya que el mundo es el encargado de interactuar con el usuario. Para guardar un valor que un usuario provee, después de crear la variable, se utiliza el método set() y se le asigna cualquier valor. Para pedir al usuario el valor, se tiene que seleccionar el mundo desde el árbol de objetos, ir a la pestaña “functions” y buscar bajo la categoría “ask user” la función para guardar el tipo de variable que se desee (ya sea number, boolean o string), se arrastra la función sobre el valor antes asignado a la variable y adicionalmente, se escribe un mensaje para que el usuario sepa lo que se le quiere preguntar. De esta manera se guarda el valor que el usuario quiera dar a la variable y podrá ser usado después.

Si por ejemplo, se quiere realizar un cálculo numérico y después se quiere presentar el resultado al usuario, se debe convertir el resultado a letras ya que los métodos “say” de los objetos de Alice sólo dicen palabras, no números. Para cambiar un valor numérico a su equivalente en string se debe declarar primero una nueva variable de tipo String y se le Apuntes Algoritmos y Programas

15


Instituto Tecnológico Autónomo de México

asigna cualquier valor, después se busca la función del mundo what.toString() que se encuentra bajo la categoría string y se arrastra en lugar del valor asignado originalmente a la variable. Después se pone como parámetro la variable con el número almacenado que se quiere convertir, por último la nueva variable string se pone en un método say del objeto que queremos lo diga y se muestre al usuario el resultado.

3.11.2. Parámetros Son uno o más datos que se necesitan pasar a un método o función para que éste pueda trabajar, es una variable que guarda un argumento para que el método que lo reciba pueda acceder a él. Básicamente se trata de enviar información pertinente al método para poder realizar la acción deseada. Ejemplos de parámetros en métodos definidos de Alice son: dirección y distancia en move, el texto en say, etc. No hay un límite para el número de parámetros que puede recibir un método o función, pero no se pueden llamar de la misma manera. Se crean dentro del método con el botón “create new parameter”.

3.11.3. Variables de propiedad o de objeto Permiten guardar un valor que describa al objeto en una propiedad, son los atributos de los objetos. Estas variables, a diferencia de las otras dos, deben definirse dentro de un objeto, ya que le permite “recordar” sus propiedades. Para crearlas hay que ir al objeto en el árbol de objetos, seleccionar la pestaña de propiedades del área de detalle y dar clic en el botón “create new variable”. Se usan de la siguiente manera: objeto.nombreDeLaVariable

3.12.

Creación de nuevas funciones

La diferencia entre métodos y funciones es que los primeros no regresan un valor porque son un mensaje para que haga algo el objeto (se espera que realicen una acción), mientras que las segundas sí regresan un único valor (se consideran una pregunta al objeto, por lo que se espera que haya una respuesta asociada) para ser usado después. Para crear una función en Alice, hay que ir al objeto, seleccionar la pestaña “functions” en el área de detalles y luego dar clic en el botón “create new function”. Al igual que con las variables, para las funciones hay que definir su nombre y el tipo de valor que va a regresar. Las funciones deben tener al final un “return statement” escrito de la siguiente Apuntes Algoritmos y Programas

16


Instituto Tecnológico Autónomo de México

manera: return variableQueRegresa; donde la variableQueRegresa debe ser del mismo tipo que la función, es la respuesta que da el objeto al realizar la función.

Al igual que los métodos, las funciones pueden tener parámetros para acceder a los argumentos que le sean enviados. Primero se debe crear la función como se describió previamente y después ya en la ventana de la función, se deben crear los parámetros que usará la función.

Apuntes Algoritmos y Programas

17


Instituto Tecnológico Autónomo de México

4. Estructuras algorítmicas 4.1.Algoritmo Es un conjunto de pasos consecutivos para resolver un problema con un fin específico. En computación “un algoritmo (del latín algobarismus) es una lista bien definida, ordenada y finita de operaciones que permite hallar la solución a un problema. Dado un estado inicial y una entrada, a través de pasos sucesivos y bien definidos se llega a un estado final, obteniendo una solución”. La importancia de un algoritmo radica en mostrar la manera de llevar a cabo procesos y resolverlos mecánicamente, los algoritmos reciben una entrada y la transforman en una salida, comportándose como una caja negra. De este modo se puede seguir y predecir el comportamiento del algoritmo para cualquier entrada posible (salvo algoritmos probabilistas, que tienen normalmente una salida distinta) a partir del seguimiento de esa secuencia de instrucciones. Un algoritmo, estrictamente hablando, no puede ejecutarse hasta que se implementa. Donald Knuth ofreció una lista de cinco propiedades, que son ampliamente aceptadas como requisitos para un algoritmo:     

Carácter finito. "Un algoritmo siempre debe terminar después de un número finito de pasos". Precisión. "Cada paso de un algoritmo debe estar precisamente definido; las operaciones a llevar a cabo deben ser especificadas de manera rigurosa y no ambigua para cada caso". Entrada. "Un algoritmo tiene cero o más entradas: cantidades que le son dadas antes de que el algoritmo comience, o dinámicamente mientras el algoritmo corre. Estas entradas son tomadas de conjuntos específicos de objetos". Salida. "Un algoritmo tiene una o más salidas: cantidades que tienen una relación específica con las entradas". Eficacia. "También se espera que un algoritmo sea eficaz, en el sentido de que todas las operaciones a realizar en un algoritmo deben ser suficientemente básicas como para que en principio puedan ser hechas de manera exacta y en un tiempo finito por un hombre usando lápiz y papel". Para nosotros eficacia debe ser también, que resuelva el problema propuesto sin desperdiciar recursos: tiempo, memoria, dinero, etc.

A las características anteriores nosotros añadiéremos Orden, ya que se debe indicar el orden de los pasos a seguir. A partir del carácter finito y de la salida, se deduce que ante una misma situación inicial (o valores de entrada) un algoritmo debe proporcionar siempre el mismo resultado (o salida) Los algoritmos pueden ser expresados de muchas maneras no obstante, se mantienen independientes de un lenguaje de programación específico.

4.2.Diagramas de Flujo Es la representación gráfica de un algoritmo que ilustra la secuencia de las operaciones que se realizan para conseguir la solución de un problema. Tiene una sintaxis propia que hay que respetar, al igual que los algoritmos son independientes de los lenguajes de programación utilizados para implementar las soluciones.

Apuntes Algoritmos y Programas

18


Instituto Tecnológico Autónomo de México

El inicio y fin de un algoritmo se representa de la siguiente manera: Inicio

Fin

El flujo de datos se indica con flechas respetando el sentido de las mismas, nunca pueden ser flechas inclinadas, ni cruzadas. Flujo de datos

Los elementos básicos de un diagrama de flujo son:

Asignación y operación (valor) (expresión) Impresión en la pantalla  say

 System.out.println();

Lectura de datos  ask user

 Scanner

Condiciones

4.3.Estructuras algorítmicas de selección Permiten tomar decisiones, es decir, si la condición se cumple se pueden realizar una serie de acciones diferentes a cuando la condición no se cumple. Hay de varios tipos que se enumeran a continuación: 4.3.1. Selectiva simple falso condició If o Si, evalúa una condición, n si ésta es verdadera ejecuta la acción, verdadero pero si es falsa no realiza acción alguna. instrucción (es)

Apuntes Algoritmos y Programas

19


Instituto Tecnológico Autónomo de México

4.3.2. Selectiva compuesta If-else Si-de_otro_modo Permite controlar la ejecución de varias acciones y se utilizan cuando se tienen 2 opciones de acción. Se debe ejecutar una o la otra, pero no ambas a la vez, es decir, son mutuamente excluyentes.

falso

verdadero condición

instrucción (es)

instrucción (es)

Este último tipo de selectivas puede anidarse (poner una dentro de otra) si hay varias condiciones hasta que alguna se cumpla. 4.3.3. Switch En lugar de un if-else anidado, para ahorrar tiempo y que sea más fácil de entender, se puede utilizar la estructura selectiva compuesta switch, siempre y cuando el selector sea de tipo entero o char y que la condición implique tomar un valor (no se puede utilizar con rangos). Se escribe de la siguiente manera: valor 1

default selector valor 2

instrucción (es)

instrucción (es)

instrucción (es)

4.4.Estructuras algorítmicas de repetición Se utilizan cuando se requiere repetir una serie de acciones varias veces, se utilizan para hacer ciclos. Hay 3 estructuras de repetición básicas for, while, do-while. 4.4.1. For Cuando se emplea esta estructura se sabe desde el principio (a priori) cuántos ciclos se van a dar, cuantas veces se realiza el ciclo. Para su correcta ejecución se vale de un contador para determinar el número de “vueltas” que se desea ejecutar. Esta estructura tiene la siguiente representación en un diagrama de flujo:

Apuntes Algoritmos y Programas

20


Instituto Tecnológico Autónomo de México

varControl  valorInicial

varControl falso < valorFinal verdadero instrucción (es)

varControl <- varControl + increm

La manera en que funciona el for es la siguiente: 1. Se define un contador con un valor inicial que marcará a partir de donde se empezará a contar. 2. Se especifica una condición para determinar si el contador excede o no el número de vueltas que se quieren dar. 3. Si no lo excede, se procede a realizar la acción que se requiera (cuerpo del for) y se aumenta el contador (normalmente en uno aunque puede variar) para saber que ya dio una vuelta y se regresa al punto 2. 4. En el momento en que la condición no se cumple se sale del ciclo y continúa ejecutando el resto del programa. 4.4.2. While Se emplea esta estructura cuando no se sabe con exactitud cuántas vueltas se van a dar en el ciclo, ya que se va a detener el ciclo hasta que se cumpla una condición específica. La condición (de tipo boolean) es evaluada antes de realizar cualquier acción, para que se inicie el ciclo, dicha condición debe cumplirse y en algún momento durante la ejecución del ciclo la condición dejará de cumplirse, dentro de las instrucciones del ciclo debe haber al menos una que modifique de forma directa o indirecta las variables involucradas en la condición para que el ciclo termine y no se cree un ciclo infinito.

Apuntes Algoritmos y Programas

21


Instituto Tecnológico Autónomo de México

falso condición

verdadero instrucción(es)

En este tipo de estructura, la o las acciones pueden llevarse a cabo cero o más veces por el hecho de que las acciones a realizar vienen después de la condición. 4.4.3. Do-while Al igual que en la estructura anterior, no se sabe cuántas vueltas va a dar el ciclo. Sin embargo, a diferencia del while, primero se realizan las acciones, después se verifica la condición y si esta sigue cumpliéndose, se vuelven a repetir las acciones hasta que la condición deje de cumplirse. Esta estructura es utilizada principalmente cuando se requiere que las acciones se realicen por lo menos una vez, lo que la diferencia de la estructura anterior.

instrucción(es)

verdadero condición falso

Todas las estructuras se pueden ir anidando (poniendo unas dentro de otras) de acuerdo a la naturaleza del problema y lo que se requiera hacer para resolverlo.

Apuntes Algoritmos y Programas

22


Instituto Tecnológico Autónomo de México

5. Conceptos básicos de Java Un programa tienen que estar escrito en un lenguaje que entienda la computadora. Existen muchos lenguajes desde ensamblador (lenguaje nemotécnico) hasta lenguajes de alto nivel: Java, Visual Basic, C++, etc. Para traducir un programa de alto nivel (programa fuente) a lenguaje máquina, se utiliza un programa llamado compilador que traduce el código fuente a lenguaje de máquina que es el programa que realmente se ejecuta. El compilador varía de acuerdo al lenguaje utilizado y a la plataforma que contenga la computadora. Programa escrito en un leguaje de alto nivel

Compilador

Programa escrito en lenguaje máquina

Java es un lenguaje de programación de alto nivel orientado a objetos, desarrollado por Sun Microsystems a principios de los años 90. La ventaja que tiene es que es independiente de la plataforma, siempre y cuando tenga instalada una máquina virtual de Java, pensando en Internet esto es sumamente importante para el desarrollo de aplicaciones. Java incluye dos partes, primero el código original pasa por un compilador dejando un archivo en código de bytes (lenguaje máquina, que no es específico de una plataforma), el cual pasa por la Máquina virtual Java (en inglés Java Virtual Machine, JVM) que es un intérprete y es el que ejecuta realmente el programa. La forma en que trabaja Java es la siguiente: se escribe un programa, se pasa por el compilador que lo hace independiente de la plataforma en la que se creó, este nuevo código lo toma la JVM que lo interpreta y ejecuta de acuerdo a la plataforma destino. Lo que permite escribir el código una vez y ser trasladado a diferentes plataformas que contengan su JVM, de ahí su popularidad y ventaja para aplicaciones en la web. Programa escrito en Java

Compilador

Código de bytes

Máquina virtual de Java

Los programas en Java pueden ser escritos en diferentes IDE’s: Entorno de Desarrollo Integrado, que son programas compuestos por un conjunto de herramientas de programación que pueden dedicarse en exclusiva a un sólo lenguaje de programación o bien, pueden utilizarse para varios. Esto implica que un programa escrito en Java puede ejecutarse en diferentes IDE’s respetando las particularidades de cada caso, sin embargo el código en sí es igual para todos.

Apuntes Algoritmos y Programas

23


Instituto Tecnológico Autónomo de México

5.1.Estructura básica de un programa La estructura básica de un programa en Java es: public class NombreClase{ public static void main(String[] args){ } } El diseño de cualquier aplicación en Java se basa en una clase, recordemos que es un lenguaje orientado a objetos, por lo que hay que poner la declaración de la clase con el class y un nombre. El método main es el método principal, cuando se ejecuta Java siempre busca el método main para iniciar la ejecución de la aplicación, es el punto de entrada y de salida de la aplicación. Si deseamos definir una clase sin main, esta debe ser instanciada en otra clase que si tenga un main, y así poder trabajar con ella.

5.2.Sintaxis Como todo lenguaje, Java tiene una sintaxis que hay que respetar:  Para Java las letras MAYUSCULAS son diferentes de las minúsculas.  Hay que declarar todas las variables a utilizar indicando su nombre y tipo antes de usarlas.  No se deben utilizar palabras reservadas para variables, métodos y/o funciones.  Toda línea de código tiene que terminar en “}”, “)” o “;” a menos que sea un cometario que puede terminar sin signo.

5.3.Tipos primitivos y referencias En Java tenemos que declarar todas las variables a utilizar, existen tipos primitivos y tipos referenciados. Se llaman tipos primitivos porque en realidad NO son objetos, lo cual hace que su uso sea más simple, los tipos referenciados SON objetos de una clase definida. En java hay 8 tipos primitivos de datos que son utilizados para guardar varios tipos de datos. Tipo Descripción Rango de valores byte Enteros pequeños -128… 127 short Enteros medianos -32,768… 32,767 int Enteros normales -2,147,483,648… 2,147,483,647 long Enteros grandes -9x1018… 9x1018 float Reales menos +-1.4e-45… +-3.4e+38 precisos double Reales más precisos +-4.9e-324… +-1.7e+308 boolean Valores lógicos Cierto o falso char Caracteres 0… 65,535, se almacena el valor numérico de cada Apuntes Algoritmos y Programas

24


Instituto Tecnológico Autónomo de México

carácter en código UNICODE Los tipos referenciados guardan la dirección de memoria de los objetos o instancias de las clases, algunas veces también son llamados tipos clases. Algunos ejemplos de éstos son: String, Scanner y System. Existen los tipos referenciados Integer, Double y String que son clases ya definidas en Java, que sólo utilizamos y que nos aportan funcionalidad para trabajar con los enteros, dobles y cadenas de caracteres:  Integer: define un objeto de tipo entero.  Double: define un objeto de tipo número con decimales.  String: define un objeto de tipo cadena de caracteres.

5.4.Expresiones, operadores y prioridad de operadores En java se pueden realizar cinco operaciones aritméticas: Nombre

Operador + * / %

Suma Resta Multiplicación División Módulo Consideraciones de los operadores:  La división entre dos enteros arroja siempre un valor entero, ejemplo: 20/7=2 .  El módulo arroja el residuo de una división entera, ejemplo: 20%7=6 .  Los operadores tienen cierta prioridad, igual a la manejada en Excel (se puede alterar utilizando paréntesis) primero * / % y después + -, siguiendo el orden de izquierda a derecha.  El operador de asignación (=) se puede utilizar para inicializar variables (ej: int numero=20;) y asignar el valor de una variable a otra (ej: a=b;, a=b+c;, double a=calculaArea(base, altura);). El operador de asignación junto con operadores aritméticos, indican diferentes operaciones como se muestra en la siguiente tabla: x+=y x-=y x*=y x/=y

x=x+y x=x-y x=x*y x=x/y

El operador (+) también se utiliza para la concatenación de Strings, es decir, unir (“pegar”) los elementos de dos o más Strings en una sola variable. El operador punto (.) se utiliza cuando es necesario que un objeto dentro de una clase acceda a los métodos y las variables de instancia de dicha clase. Aunque algunos métodos puedan tener el mismo nombre, no todos van a tener el mismo tipo y número de

Apuntes Algoritmos y Programas

25


Instituto Tecnológico Autónomo de México

parámetros, por lo que es importante fijarse qué parámetros tienen el método que se quiere invocar al utilizar este operador. Por ejemplo: alumno.setDatosAlumno(“Juan”); alumno.setDatosAlumno(“Juan López”, 000117492, “Negocios”); x.calculaAreaTriangulo(base, altura); También existen operadores de incremento y decremento: i++ equivale a i=i+1 i-- equivale a i=i-1 Los operadores relacionales se utilizan para comparar dos valores: > >= < <= == !=

mayor que mayor o igual a menor que menor o igual a igual a no igual a

Los operadores lógicos son:  &, && representan and: arroja true si todas las expresiones son verdaderas, arroja false si una de las expresiones es falsa. La diferencia entre el sencillo y el doble es que el doble puede evaluar sólo una parte de la expresión sin tener que evaluarla toda (empezando de izquierda a derecha), y el sencillo siempre tiene que evaluarla toda, es decir, si utilizamos doble & y si la primera expresión es falsa ya no evalúa las siguientes ya que arroja automáticamente false.  |, || representan or: arroja true si alguna de las expresiones es verdadera, arroja false en caso de que todas sean falsas. De manera similar al and, cuando se pone doble es para evitar que evalúe todas las expresiones: cuando encuentra una verdadera ya no evalúa al resto.  ! representa not: niega la condición de la expresión

5.5.Variables y constantes 5.5.1. Variables de instancia o atributos En java existen tres tipos de variables: de instancia (atributos), de clase y locales. Las variables de instancia se usan para guardar los atributos de un objeto particular. Ejemplo: Public class Cientifico{ private String nombre; …. }

Apuntes Algoritmos y Programas

26


Instituto Tecnológico Autónomo de México

5.5.2. Variables locales Las variables locales se utilizan dentro de los métodos y funciones, y se declaran en el momento en que son necesarias. Estas variables sólo tienen alcance dentro del método, es decir, sólo se pueden usar dentro del mismo método que las declaró (scope). Ejemplo: public int ejemplo(){ int variable; double numero; String nombre; ….. } 5.5.3. Las variables de clase Son similares a las variables de instancia, con la excepción de que los valores que guardan son los mismos para todos los objetos de una determinada clase. Por ejemplo, en el siguiente caso pi es una variable de clase y radio es una variable de instancia, pi guarda el mismo valor para todos los objetos de la clase Circulo, pero el radio de cada círculo puede ser diferente. public class Circulo { private double radio; private double pi; public Circulo(double unRadio) { radio = unRadio; pi=3.1416; } …….. 5.5.4. Variables final Una variable final es una constante, aquella a la que se le asigna un valor inicial y no se le puede asignar nunca un valor distinto, es decir, no se puede alterar su valor en el curso de la ejecución del programa. Siempre se escribe en mayúsculas para diferenciarlas de las demás. Public class Ejemplo{ private final int MAX=10; …. }

5.6.Comentarios Se utilizan los comentarios como notas explicativas/descriptivas respecto de lo que hace un método o una clase en general, el uso que se le da a una variable, cuándo se creó el programa, quién es el autor, etc., con el objetivo de que cuando otras personas (diferentes del programador) lean el programa lo entiendan con mayor facilidad o como recordatorio para el programador que lo escribió. Apuntes Algoritmos y Programas

27


Instituto Tecnológico Autónomo de México

En java existen dos tipos de comentarios básicos: en una sola línea y en varias líneas. Para los primeros, se debe utilizar el símbolo “//”; los segundos son un bloque de texto que se encuentra entre los símbolos “/*” al principio y “*/” al final.

Ejemplo: /* Clase creada el mes/año * Autor: el que escribe el programa… */ public class Ejemplo(){ //atributos private String nombre; /*metodos y constructores*/ public Ejemplo(){ } }

5.7.Sintaxis de las estructuras de control Las estructuras de control nos permiten tomar decisiones o repetir una serie de instrucciones, la sintaxis que maneja Java es la siguiente: 5.7.1. Estructuras de selección Estructura se selección simple if, permite realizar o no una acción de acuerdo a si se cumple o no una condición: If( cond){ } Estructura de selección doble if else, permite realizar una acción de acuerdo a si se cumple la condición, pero en caso de que no se cumpla se realizará otra acción. If( cond){ } else{ } Estructura se selección múltiple switch, permite realizar una de varias acciones posibles, de acuerdo al valor de una variable, la cual debe ser de tipo entera o char únicamente. Al final de cada una de las ramas del switch se debe utilizar un “break”, nótese que cada una de las ramas del switch no requiere del uso de {}.

Apuntes Algoritmos y Programas

28


Instituto Tecnológico Autónomo de México

switch (variable){ case valor1: break; case valor2: break; …… case valorn: break; default: break; } 5.7.2. Estructuras repetitivas Estructura repetitiva while, permite repetir una serie de acciones mientras la expresión lógica resulte verdadera, tiene la peculiaridad de que puede nunca realizar las acciones, ya que primero evalúa y si no se cumple no las hace. while(expression){ } Estructura repetitiva do while: permite repetir una serie de acciones mientras la expresión lógica resulte verdadera, tiene la peculiaridad de que siempre se ejecutan al menos una vez, ya que primero las realiza y después evalúa. do{

}while(expression); Nótese que es el único caso en Java que la condición de la estructura termina con es debido a que la condición denota el fin de la estructura.

;

esto

Estructura repetitiva for, es la única estructura de control que se utiliza cuando sabemos de antemano cuántas veces queremos que se repita una acción, por lo que hay que especificar el valor inicial vi, desde donde se va a contar, el valor final vf, hasta donde se va a contar y el incremento inc que debe seguir la variable var que funciona como contador. for(var=vi; var<=vf; inc){ }

5.8.Clase Math Esta clase (java.lang.Math) pública y final, proporciona varias de las funciones y constantes (E y PI) utilizadas en matemáticas. Para hacer uso de los métodos y constantes que utiliza Apuntes Algoritmos y Programas

29


Instituto Tecnológico Autónomo de México

esta clase, se deben llamar desde ella misma. Por ejemplo: Math.abs(), Math.PI, etcétera. Los métodos contenidos en esta clase son métodos estáticos (static), es decir, son métodos que para ser invocados NO requieren de la instanciación previa de un objeto de la clase, sino que para invocarlos solo se especifica el nombre de la clase . (punto) el método. A continuación se presentan algunos de los métodos que provee Java en la clase Math y que nos ayudan a escribir expresiones matemáticas complejas.

double valor; valor = Math.PI; // Valor de la constante PI valor = 90; System.out.println("\nEl seno es " + Math.sin(valor)); // Calcula seno de “valor” valor = Math.max(19, 8); // Regresa el máximo de los 2 valores dados. valor = Math.min(19, 8); // Regresa el mínimo de los 2 valores dados. valor = Math.pow(19,3); // Regresa el resultado de evaluar 19 al cubo. valor = Math.round(9.3); // Redondea el número dado. valor = Math.sqrt(9);

// Regresa la raíz cuadrada del valor dado.

valor = Math. abs(-15.3); // Regresa el valor absoluto del valor dado.

5.9.Clase String Esta clase ya definida en Java es publica y final, pertenece al paquete Java.lang y se utiliza para manejar cadenas de caracteres, como palabras o frases del estilo “abc”. Internamente maneja un arreglo de tipo char, al cual se accede a través de la variable designada. Java provee en esta clase una serie de métodos y funciones para poder trabajar con un carácter en particular, con sub cadenas o con la cadena completa. A continuación se presentan, con un ejemplo, algunos de los métodos para el manejo de este tipo de datos: /* Ejemplo de declaraciones de cadenas. Se usa la palabra reservada String (es el nombre de una clase de Java). */ String nombreCompleto, cad1, cad2; /* Declaración de variables auxiliares que se usarán para ejemplificar el empleo de los métodos provistos por Java para las cadenas de caracteres. */ Apuntes Algoritmos y Programas

30


Instituto Tecnológico Autónomo de México

char letra; int n; boolean band; // Concatenar o unir cadenas cad1.concat(nombreCompleto); cad1 = cad1 + "algo más \n"; //Cálculo de la longitud de una cadena. Si está vacía regresa 0. n = cad1.length(); /* Regresa el carácter de la posición i. * En Java, el primer carácter ocupa la posición 0. */ letra = cad1.charAt(i); // Determina si el parámetro está al inicio de la cadena. band = cad1.startsWith("gato"); // Determina si el parámetro está al final de la cadena. band = cad1.endsWith(cad2); /* Obtiene la subcadena formada desde la posición i hasta la j-1. Si j es mayor que la longitud marca error. */ cad2 = cad1.substring(i, j); cad2 = cad1.substring(0, 3); //Caracteres de las posiciones 0, 1 y 2

// Determina si dos cadenas son iguales. band = cad1.equals(nombreCompleto); // Determina si dos cadenas son iguales sin importar las mayúsculas. band = cad1.equalsIgnoreCase("gato"); /* Si el parámetro está en la cadena regresa la posición de la primer ocurrencia. Si no lo encuentra regresa -1. */ n = cad1.indexOf("algo"); /* Si el parámetro está en la cadena regresa el índice de la última ocurrencia. Si no lo encuentra regresa -1. */ n = cad1.lastIndexOf("tos"); // Convierte un entero a una cadena. cad2 = Integer.toString(9);

Apuntes Algoritmos y Programas

31


Instituto Tecnológico Autónomo de México

/* Regresa el número entero de la cadena -si ésta tuviera algún valor entero. Si no hay marca error. */ n = Integer.valueOf("90"); // Se asigna el contenido de una cadena a otra. cad2 = cad1; /* Compara las 2 cadenas: si cad1 < cad2 da negativo, si son iguales da 0 y sino positivo. */ n = cad1.compareTo(cad2); // Regresa la cadena con minúsculas -si tenía mayúsculas. cad2 = cad2.toLowerCase(); // Regresa la cadena con mayúsculas -si tenía minúsculas. cad1 = cad1.toUpperCase(); cad1= "Suerte en el examen"; // Reemplaza el primer caracter-parámetro por el segundo caracter-parámetro. cad1 = cad1.replace(" ", "");

5.10.

Import

Es una sentencia que sirve para poder tener acceso a otras clases fuera del paquete de donde se está trabajando, así se puede reutilizar el código de distintas clases. Es muy común importar la clase Scanner que nos ayuda a poder introducir datos a los programas ya sea desde el teclado (que el usuario los proporcione) o desde algún archivo. Esta clase se encuentra en el paquete java.util, para lo cual se agregaría la siguiente línea de código ANTES de declarar la clase (al inicio del programa): import java.util.Scanner;

5.11.

Clase Scanner

Se utiliza para introducir datos al programa en tiempo de ejecución, para leer u obtener datos del usuario o desde un archivo cuando se ejecuta el programa. Se debe usar de la siguiente manera: Scanner lee; lee = new Scanner(System.in); Donde: Scanner lee es la declaración de un objeto de la clase Scanner, y new Scanner(System.in) es la instanciación de dicho objeto de la clase Scanner asociándolo al buffer de entrada ligado al teclado de la computadora. Es decir, se está declarando un objeto de la clase Scanner y después se está instanciando para poder leer datos que el usuario teclee. Dentro de la clase Scanner existen una serie de funciones para leer diferentes tipos de valores: nextInt() para valores tipo int o Integer, nextDouble() para valores tipo double o Double, next() para leer una palabra de texto y nextLine() para leer una línea de texto.

Apuntes Algoritmos y Programas

32


Instituto Tecnológico Autónomo de México

5.12.

Clase System

La clase System en Java es una clase pública y final, no se instancia porque nos provee de una serie de funcionalidades (métodos y funciones) estáticas para poder ingresar datos a los programas (como se explicó en el inciso anterior), poder mandar resultados o salidas a la consola y poder manejar errores dentro del programa. Para “imprimir” (escribir) algo en la consola, se deben utilizar los siguientes comandos: System.out.print(loQueSeQuiereImprimir); System.out.println(loQueSeQuiereImprimir); //que imprime y cambia de línea. loQueSeQuiereImprimir puede ser:  Una cadena de caracteres (texto) que se desee imprimir de manera literal, en cuyo caso debe estar entre comillas dobles.  El valor asignado previamente a una variable, en cuyo caso debe ser el nombre de la variable.  Un texto combinado con valores de variables, para lo cual sebe usarse el operador de concatenación +. Ejemplo (de Alumno): Scanner lee; int claveU; Alumno a1; lee = new Scanner(System.in); System.out.println(“Dame la clave única del alumno”); //imprime en pantalla el //mensaje claveU=lee.nextInt(); //lee el siguiente entero que se escriba en el teclado a1 = new Alumno (claveU); //crea un nuevo objeto de la clase Alumno con esa clave System.out.println(“se creó un alumno con clave”+claveU);

5.13.

Instrucción Assert

El assert es una instrucción que tiene una expresión booleana y sirve para poder validar resultados del código parcialmente dentro de la ejecución de un programa, para depurar nuestro código. Es una herramienta de programación muy útil para realizar pruebas a métodos/funciones y la veracidad de los valores que arrojan. Hay que indicarle al compilador que le haga caso a la sentencia assert modificando las preferencias al correr el programa, para Elipse se realiza de la siguiente manera: se ponen en "Run Configurations" -> pestaña "Arguments" y en la caja "VM arguments" poner –ea. La forma de escribirlo es: assert expresiónBooleana: mensaje de error; Si la expresiónBooleana es verdadera la ejecución del programa continúa, de otra forma el programa deja de ejecutarse y se escribe un mensaje de error. Ejemplo assert parametro!=null: “Parametro nulo”;

Apuntes Algoritmos y Programas

33


Instituto Tecnológico Autónomo de México

5.14.

Notas importantes

Para escribir código en Java es importante recordar:  Siempre se debe de indicar el encapsulamiento de método (modificador de acceso), función y/o atributo junto con su tipo. private String nombre; // atributo public int calculo(); // método 

Cada uno de los parámetros en las funciones deben incluir su tipo. Por ejemplo: public double calcula(double b, double a)

Las funciones pueden o no regresar un valor. Si la función no regresa un valor se debe utilizar la palabra “void” al definir la función. Por ejemplo: public void nombreDelMétodo()

Si el método sí regresa un valor, se conoce como función, se debe indicar el tipo del valor que regresa y se debe usar la palabra “return” al final del método, además, el tipo del valor que regrese el método debe coincidir con el tipo de retorno del método. Por ejemplo: public boolean isWrong(){ boolean respuesta; ………. return respuesta;

 

La variable respuesta es del tipo boolean y el tipo de la función también.

} Siempre se entrecomillan “ “ las palabras comunes si se quieren usar como un String para diferenciarlas de las variables. La notación camello es la manera de escribir, en programación en java, nombres de clases, métodos y variables. Se utiliza una combinación de palabras con la inicial en minúscula y mayúscula según lo que se represente. Si se representa una clase se debe de escribir cada letra inicial de la palabra en mayúscula y sin espacios (por ejemplo: NombreClase). En caso de ser un método o variable se escribe la letra inicial de la primera palabra en minúscula y las subsecuentes iniciando en mayúsculas (por ejemplo: nombreVariable, nombreMétodo).

Apuntes Algoritmos y Programas

34


Instituto Tecnológico Autónomo de México

6. Representación de una clase en UML Para describir una clase, sus funciones y métodos, se utiliza UML (Unified Modeling Language). De esta manera, las clases se pueden representar sin importar el lenguaje de programación en el que se van a implementar. Además, sirve para ir estratificando las soluciones del problema. Es el lenguaje de modelado de sistemas de software más conocido y utilizado en la actualidad. Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema. Es importante resaltar que UML es un "lenguaje" para especificar y no para describir métodos o procesos, dice lo que tiene una clase pero no como hace la funcionalidad requerida. En otras palabras, es un estándar para describir un modelo, dice que tiene cada clase pero no como trabaja cada parte. En UML 2.0 hay 13 tipos diferentes de diagramas, solo utilizaremos los diagramas de clase. Los diagramas de clases son utilizados durante el proceso de análisis y diseño para representar las clases involucradas en el sistema, cada clase consiste de un rectángulo dividido en 3 partes por líneas horizontales: La primera parte contiene el nombre de la clase (con la primera letra mayúscula) y debe de estar centrado. El nombre debe ser claro e identificar plenamente el objeto que se desea representar. El siguiente nivel sirve para indicar los atributos de la clase, primero se coloca el nivel de encapsulamiento del atributo, luego su nombre seguido de dos puntos y por último su tipo (-, #, o + nombre: tipoAtributo). En el nivel final se colocan todos los métodos y funciones que tendrá la clase. Se le indica su nivel de encapsulamiento, su nombre seguido de dos paréntesis dentro de los cuales se incluyen los parámetros, si es que los necesita, poniendo para cada uno su tipo (no es necesario especificar el nombre de cada parámetro), finalmente se ponen dos puntos y se especifica el tipo de resultado que regresa, en caso de ser una función este tipo es obligatorio y se debe indicar, cuando se trata de un método el tipo siempre es void o el hecho de omitirlo indica que se trata de un método. (-, #, o + nombre(): tipoDeResultado). También se pueden representar herencias en los diagramas de clase UML. Para hacerlo, se debe de poner a la súper clase deseada y a las subclases debajo de esta junto con una flecha que indica cual es la clase de la que provienen. Los diagramas UML deben utilizarse en la parte de análisis del sistema, deben ser una ayuda para decidir con que clases se va a contar en la aplicación y para saber qué debe ser capaz cada una de realizar, de esta manera podemos deslindar responsabilidades en cada clase y hacer un manejo adecuado de los beneficios de la POO.

Apuntes Algoritmos y Programas

35


Instituto Tecnológico Autónomo de México

Triangulo - tipo: string - base: double - altura: double + Triangulo() +Triangulo(String, double, double) ……. +calculaArea(): double

NombreOtraClase Atributos

NombreOtraClase2 Atributos

Métodos

Métodos

 Nombre de la clase: NombreClase Atributos: nombreAtributo: tipoAtributo Métodos constructores: NombreClase Métodos  nombreMétodo (parámetros): (tipoDeAtributos) tipoDeResultadoQueRegresa

Subclases

Nota: Las clases siempre deben tener (de manera obligatoria) los métodos equals(), hashCode(), compareTo() y toString(), getAtributo() y setAtributo() que se puedan necesitar (ver siguiente sección para mayores explicaciones). Como los atributos suelen ser privados los métodos setAtributo() permiten asignarles algún valor que no haya sido asignado a través del constructor o bien cambiar algún valor previamente asignado. Las funciones getAtributo() permiten conocer el valor de un cierto atributo.

Apuntes Algoritmos y Programas

36


Instituto Tecnológico Autónomo de México

7. Clases en Java 7.1.Definición de clase En la programación orientada a objetos una clase es un modelo o molde que se puede utilizar para crear objetos. Este modelo define tanto las propiedades que deben tener los objetos como la funcionalidad de los mismos, es decir define qué características tienen (variables) y qué actividades son capaces de realizar cada uno de los objetos de la misma clase (métodos). Cuando se crea un objeto de una clase se le llama una instancia de la clase. La implementación de una clase en Java comprende dos bloques: la declaración y el cuerpo de la clase: DeclaraciónDeLaClase { CuerpoDeLaClase }

7.2.Declaración de clase Como mínimo, la declaración de una clase debe contener la palabra clave class y el nombre de la clase que está definiendo. Así la declaración más sencilla de una clase se parecería a esto: class NombreDeClase { ... } Por ejemplo, esta línea declara una nueva clase llamada Rectangulo: class Rectangulo { ... } Los nombres de las clases deben ser un identificador legal de Java y, por convención, deben empezar por una letra mayúscula. Muchas veces, todo lo que se necesitará será una declaración mínima. Sin embargo, la declaración de una clase puede decir más cosas sobre la clase. Más específicamente, dentro de la declaración de la clase se puede:  Declarar cual es la superclase de la clase, de quién hereda.  Declarar si la clase es pública, abstracta o final.  Listar las interfaces implementadas por la clase. 7.2.1. Declarar la Superclase de la Clase El término superclase se utiliza para definir la relación de herencia que existe entre dos clases, la superclase es la clase “madre” que hereda los atributos y la funcionalidad especificada a la subclase o clase “hija”. En Java, todas las clases tienen una superclase. Si no se especifica al momento de la declaración una superclase para una clase, se asume que es la clase Object (declarada en java.lang). Entonces la superclase de Rectangulo es Object porque en la declaración no se

Apuntes Algoritmos y Programas

37


Instituto Tecnológico Autónomo de México

especificó ninguna otra clase. Para obtener más información sobre la clase Object, puede ver la subsección así llamada al final de esta sección. Para indicar explícitamente la superclase de una clase, se debe poner la palabra clave “extends” seguido del nombre de la superclase, entre el nombre de la clase que se ha creado y el delimitador de bloque del cuerpo de la clase (la llave abierta) así: class NombredeClase extends NombredeSuperClase { ... } Por ejemplo: class Rectangulo extends Figura { ... } En esta declaración explícitamente se indica que la clase Figura es la superclase de la clase Rectangulo. Declarar que Figura es la superclase de Rectangulo indica implícitamente que Rectangulo es una subclase de Figura. Como una subclase hereda las variables y los métodos de su superclase, Rectangulo hereda las variables y métodos de Figura. 7.2.2. Clases Public, Abstract, y Final Se puede utilizar uno o varios de estos tres modificadores de clase en Java al momento de declarar una clase para indicar que esa clase es pública, abstracta o final. Los modificadores van delante de la palabra clave class y son opcionales.  El modificador public declara que la clase puede ser utilizada por objetos que estén fuera del paquete actual. Por omisión, una clase sólo puede ser utiliza por otras clases del mismo paquete en el que están declaradas. public class Rectangulo { ... }  El modificador abstract declara que la clase está diseñada para ser una superclase y no puede instanciarse, es una clase abstracta. Este tipo de clases se utilizan para definir partes del comportamiento de una clase, pero no está completa, contiene métodos definidos y otros métodos sin culminación, por lo que no puede tener instancias, necesita que se defina una subclase que los complete. public class abstract Figura { ... }  Utilizando el modificador final se puede declarar que una clase es final, es decir, que la clase no puede tener subclases, esto es por razones de seguridad y/o de diseño, para prevenir que una subclase altere el comportamiento de la clase y ésta deje de funcionar como es debido o porque no tiene sentido definir una subclase de esta por el diseño mismo del problema. Muchas de las clases definidas en las librerías de Java son final, precisamente para que los usuarios no puedan alterarlas. public class final Rectangulo { ... } Apuntes Algoritmos y Programas

38


Instituto Tecnológico Autónomo de México

Observa que no tiene sentido para una clase ser abstracta y final simultáneamente. En otras palabras, una clase que contenga métodos no implementados no puede ser final. Intentar declarar una clase como final y abstracta resultará en un error en tiempo de compilación. 7.2.3. Listar las interfaces que implementa la clase Una interfaz es una clase que es abstracta y que no tiene implementados sus métodos, sólo cuenta con una lista de lo que debe ser capaz de hacer un objeto de dicha clase pero no dice cómo. Cuando una clase pone en su declaración un implemets, indica explícitamente que va a definir uno o varios métodos de una o varias interfaces. public class Rectangulo implements Medidas { ... } En esta declaración vemos que la clase rectángulo va a implementar los métodos de la interfaz Medidas.

7.3.Cuerpo de la clase El cuerpo de la clase es la parte donde se declaran los atributos y la funcionalidad de la clase, se encuentra entre los delimitadores de bloque { }, que van después de la declaración de la clase. 7.3.1. Atributos Dentro del cuerpo de la clase lo primero a poner son los atributos de la clase, se declaran igual que las variables. Se pone su modificador de acceso, tipo (primitivo u otra clase) y nombre: modificador tipo nombre; public class Rectangulo { private double base; private double altura; } Los modificadores de acceso a los atributos y métodos determinan desde que clases pueden ser accedidos, pueden ser “public”, “private” y “protected”. Por omisión pueden ser utilizados desde cualquier clase del mismo paquete. Public significa que cualquier clase puede acceder a ellos, private significa que solo se puede acceder a ellos desde la misma clase y protected indica que solo las subclases de la clase en cuestión pueden acceder a ellos. Para mayor información ver los apuntes en la sección modificadores de acceso. Los atributos se recomienda que sean privados o, en ciertos casos, protegidos como se verá más adelante. 7.3.2. Constructor Después de los atributos se define la funcionalidad de la clase a través de método y/o funciones. El primer método que debe llevar una clase es el constructor, que es el método que se utiliza cuando se instancia un objeto de la clase que estamos definiendo y normalmente se utiliza para inicializar valores de los objetos. Su sintaxis es diferente a los demás métodos de la clase, se le define el modificador de acceso (público, ya que no tiene sentido declararlo privado), el nombre de la clase y entre paréntesis los parámetros necesarios para poder instanciar un objeto de esta clase (si no necesita parámetros se Apuntes Algoritmos y Programas

39


Instituto Tecnológico Autónomo de México

deben poner de todas maneras los paréntesis). Puede haber más de un constructor por clase, siempre y cuando los parámetros sean diferentes en tipo o en número. El número de constructores depende del problema y puede haber constructor nulo (sin parámetros): public nombreClase (parámetros){ } Ejemplo: public Rectangulo() { } public Rectangulo(double unaAltura, double unaBase) { altura = unaAltura; base = unaBase; } En nuestro caso, el primero es un constructor vacío y en el segundo le pedimos las dimensiones que se necesitan para instanciar un rectángulo y las almacenamos en los atributos. 7.3.3. Get’s y Set’s Después del constructor se acostumbra declarar los métodos y funciones get’s y set’s, estos métodos y funciones sirven para exponer y cambiar valores de los atributos. Como ya se indicó, los atributos se declaran normalmente privados, entonces es a través de estos métodos que otras clases puede acceder a ellos, sin embargo no todos los atributos tienen get’s y set’s, depende del problema, ya que no todos pueden ser modificados fuera de la propia clase. Los get’s son funciones que sirven para obtener o recuperar el valor de un atributo fuera de la clase, es la manera de exponer su valor, se pone el modificador de acceso, se indica el tipo de dato que regresa (el mismo tipo del atributo), como nombre se pone getAtributo y se regresa el contenido del atributo: public tipo getAtributo () { return atributo; } public double getBase() { return base; } Los set’s son métodos que sirven para cambiar el valor de un atributo una vez instanciado el objeto, hay que definir claramente a qué atributos se les puede cambiar su valor, como por ejemplo el número de una cuenta de cheques NO puede ser cambiado, pero la dirección de un cliente sí. Se pone el modificador de acceso, se indica void (ya que no regresa un valor), como nombre se pone setAtributo y entre paréntesis el nuevo valor que va a almacenar el atributo: public void setAtributo (tipo nuevoValor) { atributo= nuevoValor; }

Apuntes Algoritmos y Programas

40


Instituto Tecnológico Autónomo de México

Si quisiéramos que en tiempo de ejecución se pudieran cambiar las dimensiones del rectángulo quedaría así: public void setAltura(double otraAltura) { altura = otraAltura; } 7.3.4. Funcionalidad requerida Una vez implementados los get’s y set’s se procede a implementar la funcionalidad requerida en nuestra clase a través de métodos y/o funciones. Se especifica el modificador de acceso, tipo devuelto (para funciones y void para métodos), nombre y entre paréntesis los parámetros que necesita para trabajar (si no tiene parámetros de todas formas se ponen los paréntesis) y se ponen los delimitadores de bloque que sirven para determinar la definición del método. La mayoría de las veces, los métodos son públicos, a menos que sólo se necesite invocarlo por otro método de la misma clase. modificador tipo_devuelto nombre_metodo (parámetros){ } public double area(){ double a; a=base*altura; return a; } 7.3.5. Funcionalidad mínima requerida Además de la funcionalidad requerida de nuestra clase, de acuerdo a la naturaleza del problema, para efectos del curso, vamos a requerir otras 4 funciones como funcionalidad mínima requerida: equals(), hashCode(), compareTo() y toString(), es decir TODAS nuestras clases deben tener estas funciones como mínimo, las cuales siguen la misma sintaxis de una función normal.  equals: Es una función booleana que recibe como parámetro un objeto y sirve para ver si ambos objetos son iguales en base al valor de uno o varios de sus atributos definidos de acuerdo al problema, no indica si son el mismo objeto.  hashCode: Esta función nos devuelve un número entero que se utiliza para identificar al objeto y poder saber si son o no el mismo objeto, un uso de este identificador es cuando se manejan colecciones de objetos. Si escribimos nuestro propio método equals y no usamos el de la clase object, que está por default, es conveniente escribir nuestro propio hascode para que los criterios de comparación sean consistentes, por eso cuando generamos el código automáticamente del equals en Eclipse(IDE) nos crea automáticamente el hashCode utilizando el mismo criterio.  compareTo: Es una función entera que recibe como parámetro un objeto y sirve para comparar ambos objetos en base al valor de uno o varios de sus atributos, la comparación debe basarse en el (los) atributo(s) utilizados en la función equals(). Esta función regresa un valor negativo si el objeto es menor (en base a los atributos seleccionados) que el recibido como parámetro, 0 si son iguales y un valor positivo si es mayor.

Apuntes Algoritmos y Programas

41


Instituto Tecnológico Autónomo de México

toString: Es una función String que no tiene parámetros, su finalidad es regresar en un String toda la información que deseemos exhibir del objeto en cuestión. La clase String definida en Java resulta ser poco eficiente en términos de aprovechamiento de la memoria por lo que es conveniente programar la función toString empleando un objeto de la clase StringBuilder, para generar una cadena que posteriormente se convertirá a String. Como StringBuilder es una clase se requiere, para poderla usar, declarar e instanciar un objeto de la clase, en este caso a través del constructor nulo o por omisión. En la clase StringBuilder existen muchos métodos a los que se puede invocar, uno de ellos es el método append que concatena el String indicado entre paréntesis al objeto que lo invoca. Como todas las clases programadas en Java DEBEN contener un método toString, podemos invocar el método para obtener el String que la función toString debe regresar en función del objeto de la clase StringBuilder generado. En caso de que se le quiera dar un salto de línea a alguna parte del texto se usa el carácter de control “\n” escribiéndolo como parte del texto que se desea concatenar.

Para el ejemplo que estamos siguiendo, nuestra clase Rectangulo completa quedaría así: public class Rectangulo { private double base; private double altura; public Rectangulo() { } public Rectangulo(double unaAltura, double unaBase) { altura = unaAltura; base = unaBase; } public double getBase() { return base; } public double getAltura() { return altura; } public void setAltura(double altura) { this.altura = altura; } public boolean equals(Rectangulo otroRectangulo) { boolean resp; if (altura== otroRectangulo.getAltura() && Apuntes Algoritmos y Programas

42


Instituto Tecnol贸gico Aut贸nomo de M茅xico

base== otroRectangulo.getBase()) resp=true; else resp=false; return resp; } public int compareTo(Rectangulo otroRectangulo) { int resp; if (altura== otroRectangulo.getAltura() && base== otroRectangulo.getBase()) resp=0; else if (altura> otroRectangulo.getAltura() && base> otroRectangulo.getBase()) resp=1; else resp=-1; return resp; } public String toString(){ StringBuilder sb; sb=new StringBuilder(); sb.append("Rectangulo con:\n"); sb.append(" base "+base+"\n"); sb.append(" altura "+altura+"\n"); return sb.toString(); } public double area(){ double a; a=base*altura; return a; } public double perimetro(){ double p; p=base*2+altura*2; return p; } }

Apuntes Algoritmos y Programas

43


Instituto Tecnológico Autónomo de México

7.4. Clase Object La clase Object está situada en la parte más alta del árbol de herencia en el entorno de desarrollo de Java. Todas las clases del sistema Java son descendientes (directos o indirectos) de la clase Object. Esta clase define los estados y comportamientos básicos que todos los objetos deben tener, como la posibilidad de compararse unos con otros, de convertirse a cadenas, de esperar una condición variable, de notificar a otros objetos que la condición variable ha cambiado y devolver la clase del objeto. 7.4.1. El método equals() equals() se utiliza para comparar si dos objetos son iguales. Este método devuelve true si los objetos son iguales, o false si no lo son. Observe que la igualdad no significa que los objetos sean el mismo objeto. Cuando dentro de una clase se define su propio método equals, se está sobrescribiendo este método y la clase le va a hacer caso al nuevo que se definió. 7.4.2. El método getClass() El método getClass() es un método final (no puede sobrescribirse) que devuelve una representación en tiempo de ejecución de la clase del objeto. Este método devuelve un objeto Class al que se le puede pedir información sobre la clase, como su nombre, el nombre de su superclase y los nombres de los interfaces que implementa. 7.4.3. El método toString() Este método devuelve una cadena de texto que representa al objeto. Es decir, arroja una variable de tipo String que muestra el contenido de todos los atributos que conforman al objeto. De igual manera que con el método equals, cuando dentro de una clase se define su propio método toString, se está sobrescribiendo este método y la clase le va a hacer caso al nuevo que se definió. 7.4.4. Otros métodos de Object La clase Object proporciona un método, finalize() que limpia un objeto antes de recolectar la basura y limpiar la memoria. La clase Object también proporciona otros cinco métodos: 

notify()

notifyAll()

wait() (tres versiones)

Estos últimos métodos no se explican ya que quedan fuera del alcance del curso.

Apuntes Algoritmos y Programas

44


Instituto Tecnológico Autónomo de México

8. Modificadores de acceso en Java Los modificadores de acceso se utilizan para restringir el uso de clases, completas o de algún miembro de ellas, se hace a través de palabras clave en las declaraciones con el objetivo de indicar quien y a que parte de una clase se puede tener acceso. Es muy importante utilizar correctamente estos modificadores, desde el diseño de las clases se debe definir a que queremos que se tenga acceso y quienes queremos que tengan acceso, para no comprometer la información almacenada en los objetos. . Llamaremos miembros de forma genérica a todos estos atributos o variables, métodos y funciones que están definidos dentro de una clase.

8.1.Accesar a los Miembros de la Clase El lenguaje Java soporta cuatro niveles de acceso para los miembros de una clase: private, protected, public y si no se especifica alguno, se utiliza el modificador por default de paquete. 8.1.1. Private El nivel de acceso más restringido es “private”. Un miembro privado es accesible sólo para la clase en la que está definido. Se utiliza este acceso para declarar miembros que sólo deben ser utilizados por la clase. Esto incluye las variables (atributos) que contienen información que en caso de acceder a ella desde el exterior podría colocar al objeto en un estado de inconsistencia, o para los métodos que llamados desde el exterior, pueden poner en peligro el estado del objeto o del programa donde se está ejecutando. Para declarar un miembro privado se utiliza la palabra clave private en su declaración, por ejemplo: private int clave;

Esto significa que el atributo clave sólo puede ser utilizado dentro de la misma clase. 8.1.2. Protected El modificador de acceso “protected” permite a la propia clase, las subclases y todas las clases dentro del mismo paquete acceder a los miembros. Este nivel de acceso se utiliza cuando es apropiado para una subclase de la clase tener acceso a los miembros de la clase “madre”, pero no las clases no relacionadas, por ejemplo: protected JButton btnCompra, btnVenta, btnInfo;

Esta línea está declarando tres botones en una ventana, donde todas las clases que se deriven de esta van a poder acceder a los botones para realizar operaciones. 8.1.3. Public El especificador de acceso más sencillo es “public”. Todas las clases, en todos los paquetes tienen acceso a los miembros públicos de una clase. Los miembros públicos se declaran sólo si su acceso no pone en riesgo la seguridad e integridad de la clase, por lo que se debe tener cuidado al utilizarlo. Por ejemplo: public int edad;

Apuntes Algoritmos y Programas

45


Instituto Tecnológico Autónomo de México

Al poner que el atributo edad es público, significa que cualquier otra clase puede tener acceso al valor del atributo y lo puede modificar, normalmente los atributos no se deben declarar públicos, ya que resulta peligroso para la seguridad de la información de los objetos, lo que se hace es definir “private” o “protected” los atributos y utilizar los métodos get’s y set’s para poder modificar o acceder a estos atributos. Para los métodos o funciones es más común definirlos públicos, a menos que sea una funcionalidad que sólo deba hacerse dentro de la misma clase. 8.1.4. Acceso de Paquete El último nivel de acceso es el que se obtiene si no se especifica ningún otro nivel de acceso a los miembros. Este nivel de acceso permite que todas las clases de un mismo paquete tengan acceso a los miembros así declarados. Por ejemplo: boolean resp;

La siguiente tabla muestra los niveles de acceso permitidos por cada modificador: Especificador private protected public package

clase subclase paquete X X X X X X X X X

otra

X

La primera columna indica si la propia clase tiene acceso al miembro definido por el modificador de acceso. La segunda columna indica si las subclases de la clase (sin importar dentro de que paquete se encuentren estas) tienen acceso a los miembros. La tercera columna indica si las clases del mismo paquete que la clase en cuestión (sin importar su parentesco) tienen acceso a los miembros. La cuarta columna indica si cualquier otra clase (fuera del paquete y sin relación alguna) tienen acceso a los miembros.

8.2.Accesar a una Clase Las clases solo tienen dos modificadores de acceso, es decir solo pueden utilizar public o no poner nada lo que significa friendly. 8.2.1. Public Una clase pública indica que cualquiera puede tener acceso a esa clase, es decir, se pueden hacer instancias de esa clase siempre y cuando se tenga un constructor accesible. Por ejemplo: public class Hospital{

8.2.2. Friendly ¿Qué sucede si no se indica ningún tipo de especificador de acceso a la clase? entonces se define implícitamente como amistoso lo cual significa que todas las clases del paquete, donde se encuentre definida, tienen acceso a la clase, pero todas las clases fuera del paquete no tienen acceso a esta clase. El acceso amistoso permite agrupar clases relacionadas en un mismo paquete de forma que estas puedan interactuar entre sí de forma sencilla.

Apuntes Algoritmos y Programas

46


Instituto Tecnológico Autónomo de México

9. Manejo de Objetos en Java 9.1.Creación En Java, se crea un objeto instanciando una clase (creando una instancia de la clase de la cual se desea un objeto). La creación de un objeto en Java se hace con una sentencia como esta: Rectagulo rec = new Rectangulo();

Con esta sentencia crea un (nuevo) objeto Rectangulo y se realizan tres acciones:  declaración,  instanciación e  inicialización. rec es una variable que sólo le dice al compilador que el nombre rec se va a utilizar para referirse a un objeto cuyo tipo es Rectangulo, el operador new instancia la clase Rectangulo (creando un nuevo objeto Rectangulo), y Rectangulo() es el constructor nulo con el que se inicializa el objeto.

9.2.Declararación La declaración de un objeto es una parte necesaria de la creación de un objeto, sin embargo las declaraciones aparecen frecuentemente en la misma línea que la creación del objeto. Como cualquier otra declaración de variable, las declaraciones de objetos pueden aparecer solas como esta: Rectangulo rec;

De la misma forma, declarar una variable para contener un objeto es exactamente igual que declarar una variable que va a contener un tipo primitivo: tipo nombre;

Donde tipo es el tipo de dato del objeto (la clase) y nombre es el nombre con el que se hará referencia al objeto. Las declaraciones notifican al compilador que se va a utilizar nombre para referirse a una variable cuyo tipo es tipo. Las declaraciones no crean nuevos objetos. Rectangulo rec no crea un objeto Rectangulo, sólo crea un nombre de variable que hace referencia al objeto Rectangulo, que hasta este momento es nulo, no se ha instanciado, es necesaria esta declaración ya que a través del nombre de esta variable vamos a acceder al objeto una vez instanciado.

9.3.Instanciación El operador new instancia un objeto de una clase y asigna memoria para el objeto nuevo de ese tipo, este operador precede una llamada al método constructor de la clase que inicializa el objeto. Los métodos constructores son métodos especiales de cada clase en Java y son responsables de la inicialización de los nuevos objetos de ese tipo. El operador new crea el objeto y el constructor lo inicializa. El operador new devuelve una referencia al objeto recién creado y esta referencia es almacenada en la variable. Apuntes Algoritmos y Programas

47


Instituto Tecnológico Autónomo de México

rec = new Rectangulo();

9.4.Inicialización Las clases proporcionan métodos constructores para inicializar los nuevos objetos de ese tipo. Los constructores tienen el mismo nombre que la clase y no tienen tipo de retorno. Cada clase debe tener al menos un constructor, pero puede contener más de uno para realizar diferentes tipos de inicialización en los nuevos objetos. Si una clase tiene varios constructores, todos ellos tienen el mismo nombre pero se deben diferenciar en el número o el tipo de sus argumentos (parámetros) que cada uno utiliza. El constructor de Rectangulo utilizado no tenía ningún argumento (parámetro): Rectangulo();

Un constructor que no tiene algún argumento es conocido como constructor por default (o por omisión) o nulo. Al igual que Rectangulo, la mayoría de las clases tienen al menos el constructor por omisión.

9.5.Referenciar Variables de un Objeto Para acceder a las variables (atributos) de un objeto, sólo se tiene que añadir el nombre de la variable al del objeto referenciado introduciendo un punto en el medio ('.'). objetoReferenciado.variable rec.x = 15; rec.y = 37;

Esto es posible siempre y cuando los atributos de la clase en cuestión sean públicos (public), pero como ya se explicó anteriormente no es conveniente tener atributos públicos, por lo que se deben utilizar los métodos y funciones get y set para acceder a ellos.

9.6.Llamar a Métodos de un Objeto Llamar a un método de un objeto es similar a obtener una variable del objeto. Para llamar a un método del objeto, simplemente se añade al nombre del objeto referenciado el nombre del método, separados por un punto ('.') y se proporcionan los argumentos del método entre paréntesis. Si el método no necesita argumentos (parámetros), se utilizan los paréntesis vacíos. objetoReferenciado.nombreMétodo(listaArgumentos); o objetoReferenciado.nombreMétodo(); Ejemplo: rec.calculaArea(); rec.setX(15);

9.7.Eliminar Objetos no Utilizados Muchos otros lenguajes de programación orientados a objetos diferentes de Java necesitan que se siga la pista de los objetos que se han creado y luego se destruyan Apuntes Algoritmos y Programas

48


Instituto Tecnológico Autónomo de México

cuando no se necesiten. Java permite ahorrarse esto, permitiendo crear tantos objetos como se quiera (sólo limitados por los que el sistema pueda manejar) pero nunca tienen que ser destruidos. El entorno de ejecución Java borra los objetos cuando determina que no se van a utilizar más. Este proceso es conocido como recolección de basura. Un objeto es elegible para la recolección de basura cuando no existen más referencias a ese objeto. Las referencias que se mantienen en una variable desaparecen de forma natural cuando la variable sale de su ámbito o alcance. Se puede borrar explícitamente un objeto asignándole a su referencia (a la variable) el valor null.

9.8.Recolector de Basura El entorno de ejecución de Java tiene un recolector de basura que periódicamente libera la memoria ocupada por los objetos que no se van a necesitar más. El recolector de basura funciona en un thread (hilo) de baja prioridad y funciona tanto síncrona como asíncronamente dependiendo de la situación y del sistema en el que se esté ejecutando el entorno Java.

9.9.Finalizar Antes de que un objeto sea recolectado para su eliminación, el recolector de basura le da una oportunidad para limpiarse él mismo mediante la llamada al método finalize() del propio objeto. Este proceso es conocido como finalización. Durante la finalización un objeto se pude liberar los recursos del sistema como son los archivos, etc. y liberar referencias de otros objetos para hacerse elegibles por la recolección de basura. El método finalize() es un miembro de la clase java.lang.Object. Una clase debe sobrescribir el método finalize() para realizar cualquier finalización necesaria y específica para los objetos de ese tipo, si así se requiere.

Apuntes Algoritmos y Programas

49


Instituto Tecnológico Autónomo de México

10.

Subclases, Superclases, y Herencia

En Java las clases se pueden derivar desde otras clases. La clase derivada (la clase que proviene de otra clase) se llama subclase. La clase de la que está derivada se denomina superclase. El término superclase se utiliza para definir la relación de herencia que existe entre dos clases, la superclase es la clase “madre” que hereda los atributos y la funcionalidad especificada a la subclase o clase “hija”. La clase de la que todas las demás descienden, es la clase Object (java.lang). Object es la raíz de la herencia de todas las clases. Las subclases heredan el estado y el comportamiento en forma de las variables y los métodos de su superclase. La subclase puede utilizar los ítems heredados de su superclase tal y como son, o puede modificarlos o sobrescribirlos.

10.1.

Crear Subclases

Para indicar que una clase es una subclase de otra clase, debe especificarse dentro de la declaración de Clase incluiyendo la cláusula extends. Por ejemplo, supongamos que queremos crear una subclase llamada SubClase de otra clase llamada SuperClase. Se escribiría esto: class SubClass extends SuperClass { ... }

Una clase Java sólo puede tener una superclase directa, es decir, Java no soporta la herencia múltiple, sin embargo, una subclase también hereda variables y miembros de las superclases de su superclase, y así a lo largo del árbol de la herencia siguiendo ciertas reglas:  Heredan aquellos atributos declarados como public o protected.  Heredan aquellos atributos declarados sin especificador de acceso (normalmente conocidas como friendly) siempre que la subclase esté en el mismo paquete que la clase.  No heredan aquellos atributos de la superclase si la subclase declara otro atributo que utiliza el mismo nombre. El atributo de la subclase se dice que oculta al atributo o variable miembro de la superclase.  No hereda las variables miembro o atributos private.  Hereda aquellos métodos declarados como public o protected.  Hereda aquellos métodos sin especificador de acceso, siempre que la subclase esté en el mismo paquete que la clase.  No hereda un método de la superclase si la subclase declara un método que utiliza el mismo nombre. En este caso se dice que el método de la subclase sobrescribe al método de la superclase.  No hereda los métodos private.

Apuntes Algoritmos y Programas

50


Instituto Tecnológico Autónomo de México

10.2.

Sobrescribir Métodos

Es la habilidad de una subclase para redefinir un método de su superclase, permite a una clase heredar de su superclase aquellos comportamientos "más cercanos" y luego suplementar o modificar el comportamiento de la superclase. Una subclase puede sobrescribir completamente la implementación de un método heredado o puede completar, mejorar o hacer más específico el método añadiéndole funcionalidad. Métodos que una Subclase no puede sobrescribir:  Una subclase no puede sobrescribir métodos que hayan sido declarados como final en la superclase.  Una subclase tampoco puede sobrescribir métodos que se hayan declarado como static en la superclase. Métodos que una Subclase debe sobrescribir:  Las subclases deben sobrescribir aquellos métodos que hayan sido declarados como abstract en la superclase, o la propia subclase debe ser abstracta.

Apuntes Algoritmos y Programas

51


Instituto Tecnológico Autónomo de México

11.

Arreglos

11.1.

Características, declaración e instanciación

Los arreglos son colecciones de datos del mismo tipo, estos se almacenan en posiciones consecutivas de memoria y reciben un nombre común, es decir los datos que se guarden en un arreglo deben de ser siempre del mismo tipo. Además los arreglos no cambian de tamaño, son estructuras de datos estáticas. Los arreglos pueden ser de tipos primitivos o se puede crear un arreglo de tipo de una clase, si se quieren guardan instancias (objetos) de alguna clase en particular. Si vemos gráficamente a un arreglo cualquiera, se vería como una serie de casillas (o celdas) de memoria que pueden contener alguna información. Supongamos que tenemos un arreglo con un límite de 5. nomArr Posición Posición Posición Posición Posición 0 1 2 3 4 Como se puede observar, a cada casilla se le asigna un número que indica su posición dentro del arreglo y, como particularidad, la primera casilla comienza en cero (0) en vez de uno (1). Esto se debe de considerar al momento de manejar el arreglo ya que es fácil confundir la posición. A esta posición se le conoce como índice y a través de él se accede a la celda deseada de un arreglo: el acceso a los elementos de un arreglo es directo. En la realidad el nombre de un arreglo es una variable (casilla de memoria) que almacena la dirección de memoria del primer dato del arreglo, aquel que está en la posición 0. 11.1.1. Declaración Existen dos maneras, igualmente válidas, de declarar arreglos en Java: tipo nombreArreglo []; tipo [] nombreArreglo; Ejemplos de declaraciones validas: String arrelgo1[]; int arreglo2[]; //tipo objeto Coche [] automotriz; 11.1.2. Instanciación Para trabajar con arreglos en Java no basta declararlos hay que instanciarlos también, al momento de instanciarlo se le debe de asignar el máximo número de elementos que guardará, esto se hace al indicarlo con una constante entera (int) o con una variable cuyo contenido sea el número de celdas que se desea tenga el arreglo. Este número entero determina el número de datos que se le pueden asignar, es un límite en el número de casillas que maneja, si se quiere seleccionar una casilla mayor a la definida se crea un error llamado “overflow”, que Java reporta como:

Apuntes Algoritmos y Programas

52


Instituto Tecnológico Autónomo de México

java.lang.ArrayIndexOutOfBoundsException. Esto significa que se quiere acceder a un espacio de memoria no asignado del arreglo y el código colapsará. nombreArreglo= new tipoArreglo[MAXIMO]; Ejemplo: arreglo1= new String[20]; int final MAX=25; arreglo2=new int[MAX]; Nota: en caso de que se use una variable, se recomienda que sea final (es decir una constante) ya que tiene la característica de que nunca cambia durante la ejecución del programa. Se puede declarar e instanciar un arreglo en la misma línea, aunque está prohibido si el arreglo es un atributo en alguna clase, en ese caso se debe instanciar en su constructor. Ejemplo de declaración de arreglos en una clase: public class Calificaciones{ private double calif[]; private final int MAX=10; public Calificaciones{ calif= new double[MAX]; } }

11.2.

Asignación de un valor a una posición específica del arreglo

El asignar un valor a un elemento de un arreglo es bastante similar al de hacerlo con una variable, la diferencia radica en que se debe indicar a que celda del arreglo se desea asignar el valor en cuestión. También se le puede asignar cualquier variable u objeto al arreglo siempre y cuando sea del mismo tipo que el arreglo y no se le quiera asignar a una casilla que no exista en el arreglo (overflow). Asignación nombreArreglo[numElemento] = valor; Ejemplos: arreglo2[0]=15; arreglo[0] =nombre; automotriz[0]= new Coche(); Ejemplo gráfico: Supongamos que tenemos un arreglo de tipo int llamado arreglo2 con 25 casillas arreglo2[0]=15; arreglo2[1]=2; arreglo2[2]=3; arreglo2[3]=6;

Apuntes Algoritmos y Programas

53


Instituto Tecnológico Autónomo de México

Índice del arreglo 0

1

2

3

4

15

2

3

6

0

24

0

Si no se llena completamente el arreglo, sus demás casillas se quedan con el valor nulo del tipo de datos con el que está definido el arreglo, 0 para enteros, 0.0 para doubles y Null para objetos. Estas celdas se pueden llenar en cualquier otro momento.

11.3.

Acceso a un elemento del arreglo

Igual que con la asignación, el tener acceso a un elemento de un arreglo, es similar a trabajar con una variable, simplemente hay que especificar el nombre del arreglo y el índice o posición deseada. Ejemplo: En este caso, se toma la primera public double calculaAlgo(){ casilla del arreglo y la multiplica por return arreglo2[0]*2; dos, por lo tanto, el cálculo seria de } 15*2 y da como resultado 30. 11.3.1. Automatización En caso de que se usen arreglos muy grandes, es poco útil asignar o llamar los elementos uno por uno. Para evitar escribir código redundante y cuando se quiera trabajar con TODOS los elementos del arreglo se usa un ciclo for, para hacer el proceso más fácil y rápido, esto con la precaución de no exceder el límite del arreglo ya que se causaría un overflow y el código colapsaría. Se recomienda usar una variable para no tener que manejar números y se cometan errores. Ejemplo: Representación int suma; gráfica 0 1 2 3 4 int final MAX=5; 1 1 1 1 1 int arre[ ]=new int[MAX]; El resultado de la suma es 5. //uso del ciclo for para llenar el arreglo con 1 (1+1+1+1+1=5) for(int i=0; i<MAX; i++) arre[i]=1; //uso de for para recorrer el arreglo accediendo a cada una de las celdas del mismo for(int j=0; i<MAX; j++) suma=suma+arre[j];

11.4.

Aumentar la capacidad de un arreglo

¿Qué hacer cuando un arreglo se llena y se desean guardar más datos? este escenario puede ocurrir cuando se presenta una cantidad no anticipada de información. Como antes se mencionó, un arreglo no puede aumentar su capacidad pero se puede crear otro arreglo que tome su lugar y tenga un tamaño mucho más grande.

Apuntes Algoritmos y Programas

54


Instituto Tecnológico Autónomo de México

Ejemplo: int capacidad=3; int arre[ ]= new arre[capacidad]; //El arreglo se llena de 2s for(int i=0,i<capacidad;i++) arre[i]= 2; En el arre ya no caben más elementos, por lo que se debe escribir un método para “ampliar” la capacidad del arreglo: public void aumentaCap(int [ ] arre){ //se crea un nuevo arreglo con el doble de capacidad que el arreglo original int arreN[ ]= new arre[arre.length*2]; //Se llena el nuevo arreglo con los datos del anterior for(int j=0; j<capacidad;j++) arreN[j]=arre[j]; //se sutitutye el nuevo arreglo por el viejo arre=arreN; } Notas importantes: arreglo.length arroja el tamaño de arreglo, el número de celdas con las que fue definido (instanciado). Como el nombre de un arreglo es una dirección de memoria, cuando se usa como parámetro en un método, su valor puede resultar alterado (lo que efectivamente pasa en el método anterior), a esto se conoce como paso de parámetro por referencia. Volviendo a nuestro ejemplo original, faltaría agregar una línea de código para invocar al método anterior: int capacidad=3; int arre[ ]= new arre[capacidad]; //El arreglo se llena de 2s for(int i=0,i<capacidad;i++) arre[i] = 2; //se duplica la capacidad de arre aumentaCap(arre); //ahora si ya se pueden agregar más elementos en arre: arre[capacidad] = 3;

11.5.

Corrimientos

Se pueden hacer “movimientos” dentro de los arreglos, es decir, se pueden cambiar de lugar los elementos del arreglo como se necesite, por ejemplo si se quiere eliminar o insertar algún elemento del arreglo o si se quieren ordenar los elementos. Existen ciertos movimientos básicos en los arreglos:

Apuntes Algoritmos y Programas

55


Instituto Tecnológico Autónomo de México

11.5.1. Corrimiento a la derecha Es un método para “correr” los elementos de un arreglo K lugares a la derecha, este método pide como parámetros el arreglo, el tamaño del arreglo y el número de veces que se recorren los elementos public static void corrimientoDer(double [] a, int n, int k){ for (int j=1; j<=k; j++){ for (int i = n-1; i>0; i--) a[i] = a[i-1]; a[0]=0; } } 11.5.2. Corrimiento a la izquierda Es un método para “correr” los elementos de un arreglo K lugares a la izquierda, este método pide como parámetros el arreglo, el tamaño del arreglo y el número de veces que se recorren los elementos public static void corrimientoIzq(double [] a, int n, int k){ for (int j=1; j<=k; j++){ for (int i=0; i<n-1; i++) a[i]=a[i+1]; a[n-1]=0; }

11.6.

Intercambio de elementos

Para intercambiar elementos de lugar en un arreglo se utiliza el método swap, para lo cual hay que guardar el elemento de una posición en una variable auxiliar (para no perder le valor) y así intercambiar de lugar con el otro elemento de otra posición en particular. Los parámetros son: el arreglo y las posiciones de los elementos a intercambiar. public static void swap(double []a, int posX, int posY){ double aux; //se guarda el primer elemento en la variable auxiliar aux=a[posX]; //se remplaza el primer elemento con el segundo a[posX]=a[posY]; //se coloca el primer elemento guardado en el lugar del segundo elemento a[posY]=aux; }

11.7.

Ordenamiento por selección directa

Existen innumerables algoritmos de ordenamiento, que aplican sobre diferentes estructuras de datos. A continuación se aplicará y explicará el método de ordenamiento por Selección Directa, para ordenar los elementos de un arreglo de menor a mayor.

Apuntes Algoritmos y Programas

56


Instituto Tecnológico Autónomo de México

La Selección Directa propone recorrer el arreglo n-1 veces, donde n es el número de celdas ocupadas del arreglo. En cada recorrido (o vuelta) se “revisan” desde la celda i (cero la primera vez, uno la siguiente, etc.) hasta la celda n-1, buscando garantizar que el elemento más pequeño del arreglo se deje en la primera celda (cero la primera vez, uno la siguiente, etc.). El método es void ya que no regresa un resultado por sólo cambiar de lugar los elementos del arreglo, nuevamente se aprovechara la condición de dirección de memoria del nombre del arreglo y pasa como parámetro por referencia al método, esperando ser alterado al finalizar el mismo. Para poder utilizar este método es necesario usar otros dos. El primero es el método swap (ya mencionados antes) y el segundo es el método posMinimo que arroja el índice (o posición) donde se encuentra el elemento más pequeño de un arreglo desde una cierta celda hasta la celda n-1. 11.7.1. Código de posición del mínimo Recibe como parámetros: el arreglo, su longitud y la posición donde iniciarán las comparaciones: public static int posMinimo(double [] arreglo, int n, int inicio){ //se asigna la posición donde se empieza a buscar el mínimo int min=inicio; for(int i=inicio+1; i<n; i++) //compara al elemento determinado como mínimo vs el elemento i if(arreglo[min]>arreglo[i]) //si encuentra uno menor se obtiene su índice dentro del arreglo min=i; return min; } 11.7.2. Código de selección directa Se reciben el arreglo y su tamaño como parámetros public static void seleccionDirecta(double [] a, int n){ //se crea una variable que guardará el elemento menor int min; for(int i=0; i<n-1; i++){ //se hace la comparación entre los elementos min=posMin(a,n,i); swap(a,min,i); } }

11.8.

Búsquedas en arreglos

Al momento de buscar un elemento en un arreglo se debe saber si está ordenado o desordenado. En el caso de que el arreglo se encuentre desordenado, se tendrá que Apuntes Algoritmos y Programas

57


Instituto Tecnológico Autónomo de México

buscar elemento por elemento hasta que el objetivo (elemento buscado) sea encontrado o el arreglo se acabe. Si el arreglo está ordenado se hará la búsqueda hasta encontrarlo o hasta encontrar otro que sea mayor que el buscado, si ocurre lo último se sabe que el elemento no se encuentra en el arreglo. El resultado que arrojan las búsquedas es la posición del elemento, si es que se encuentra en el arreglo, o el negativo de la posición donde debería encontrarse el objetivo menos 1 (posición * -1), esto si el arreglo está ordenado, en caso de que el arreglo esté desordenado y el elemento buscado no se encuentre, la función deberá arrojar -1. 11.8.1. Código de búsqueda secuencial ordenada Los parámetros son: el arreglo, su longitud y el elemento a buscar public static int buscaSecuencialOrdenada(double [] a, int n, double x){ int i=0; /*Se realiza la búsqueda mientras no se termine el arreglo y no se encuentre un elemento mayor que el que se busca */ while (i<n && a[i]<x) i++; /* al salir del while ,si la posición encontrada es igual a la longitud del arreglo o el elemento en la posición encontrada es diferente al que se busca se regresa la posición como negativa */ if (i>=n || a[i]!=x) i=-i-1; return i; } 11.8.2. Código de búsqueda secuencial desordenada. Los parámetros son: el arreglo, su longitud y el elemento a buscar public static int buscaSecuencialDesordenada(double [] a, int n, double x){ //se incia la posición en 0 int i=0; /*se usa un while para buscar el elemento hasta que se encuentre o se acabe el arreglo */ while (i<n && a[i]!=x) //si todavía no aparece se aumenta la posición i++; //al salir del while si la posición es igual a la longitud del arreglo //significa que no se encontró if (i==n) i=-1; return i; }

Apuntes Algoritmos y Programas

58


Instituto Tecnológico Autónomo de México

11.8.3. Búsqueda binaria Este tipo de búsqueda sólo funciona si el arreglo está ordenado y tiene la ventaja que es el más eficiente que hay. Esto se debe a que selectivamente elije el lugar donde comienza a buscar el elemento deseado y va dividiendo el arreglo entre 2 hasta encontrar el objetivo (elemento buscado). Imaginemos que tenemos un arreglo de 8 elementos y queremos buscar el que contiene el número 8. -1

2

4

5

8

9

10

12

La búsqueda tiene 3 variables al comenzar, que se utilizan para indicar el índice que marque el inicio, el fin y la mitad del arreglo. El fin se obtiene con la longitud del arreglo y siempre se le resta 1 (n-1) ya que cabe recordar que el índice del arreglo comienza en cero y termina en n-1. La mitad se obtiene al hacer la división entre 2 de la suma del inicio y el fin, esta división es división entera, ya que los índices de los arreglos son siempre enteros (no hay medias casillas de memoria). El algoritmo pregunta por la coincidencia de que el objetivo se encuentre en la mitad del arreglo y de que el inicio siga siendo menor o igual al fin. Si el objetivo se encuentra, el algoritmo termina, si no, se elige con qué mitad del arreglo continuará la búsqueda: si el objetivo es más pequeño que el elemento que se encontró en la mitad, entonces la variable fin deberá valer ahora mitad-1 (debe buscar en la primera mitad ya que es menor al elemento encontrado en la mitad del arreglo y están ordenados), si en cambio, el objetivo es mayor al elemento que se encontró en la posición mitad del arreglo entonces el inicio deberá valer mitad+1 (ya que es mayor) y repetir la revaloración de mitad para volver a preguntar por la coincidencia entre el valor ubicado en la posición mitad y el objetivo. Lo que se hace es ir cortando el arreglo a la mitad, y ésta a su vez a la mitad y así sucesivamente hasta encontrar el elemento que se desea, por eso el nombre de binario. El proceso se repite hasta que se encuentre el elemento o se determine que no está, en este caso el fin se vuelve menor que el inicio y ya no hay dónde buscar, esto significa que el elemento no se encuentra en el arreglo. Los parámetros son el arreglo, su longitud y el elemento que se quiere buscar public static int buscaBinaria(int [] a, int n, int x){ int pos; int inicio = 0; int fin = n-1; // como inicio, fin y 2 son enteros hace división entera! int mitad = (inicio+fin)/2; while ( inicio <= fin && a[mitad]!=x ) { if ( x < a[mitad] ) fin = mitad-1; Apuntes Algoritmos y Programas

59


Instituto Tecnológico Autónomo de México

else inicio = mitad+1; mitad = (inicio+fin)/2; } if ( inicio > fin ) // elemento no encontrado pos = -inicio-1; else pos = mitad; return pos; }

11.9.

Uso de arreglos del tipo <T>

Java tiene la ventaja de tener definido un tipo genérico <T> (de Type), que nos permite escribir código general para cualquier tipo y T toma su valor real hasta el tiempo de ejecución. Esto nos permite ahorrar mucho tiempo y líneas en la codificación, ya que el mismo código sirve para varios tipos sin tener que estar definiendo uno para cada uno, lo que implicaría tener códigos “iguales” para diferentes tipos. En el caso de los arreglos nos permite definir código para trabajar con ellos sin tener que estar especificando si son Integer, Doubles u objetos de cierta clase. Es decir pueden almacenar cualquier elemento siempre que pertenezcan a la misma clase T con la que se declaró el arreglo. La clase que va a remplazar al tipo genérico T debe cumplir con ciertas condiciones, no es sólo una clase cualquiera, debe tener definido los métodos equals() y compareTo(), de esta manera se pueden comparar los objetos entre sí y utilizar las operaciones que se han visto previamente en el manejo de arreglos. 11.9.1. Swap con arreglos genéricos En este caso, el método swap es un método estático y ahora se convertirá en un método estático y genérico aumentando <T> en el encabezado, es decir, puede ser invocado para actuar sobre cualquier arreglo de cualquier tipo. public static <T> void swap(int posX, int posY, T [] a){ T aux; aux=a[posX]; a[posX]=a[posY]; a[posY]=aux; } Cuando se hace una comparación entre los elementos del arreglo definido como genérico se debe de agregar <T extends Comparable> en el encabezado del método estático, lo que indica que la clase que va a reemplazar al tipo <T> tiene definido su compareTo() y/o equals(),si no, marca error y no lo puede sustituir, esto es para que el método estático pueda llamar a estos métodos y hacer las comparaciones entre objetos de la misma clase. La clase que queremos que remplace al tipo T debe tener en su encabezado un Apuntes Algoritmos y Programas

60


Instituto Tecnológico Autónomo de México

implements, que indica explícitamente que tiene implementado el compareTo(), quedando el encabezado así: public class nomClase implements Comparable< nomClase >{ 11.9.2. Posición del mínimo con genéricos Para buscar el mínimo en un arreglo genérico, el código nos quedaría así: public static <T extends Comparable> int posMinimo(T [] arreglo, int n, int inicio){ int min=inicio; for(int i=inicio+1; i<n; i++) //compara al elemento determinado como mínimo vs el elemento i if(arreglo[min].compareTo(arreglo[i])<0 ) //si encuentra uno menor se obtiene su índice dentro del arreglo min=i; return min; }

Apuntes Algoritmos y Programas

61


Instituto Tecnológico Autónomo de México

12.

Arreglos con lectura de archivos

Los datos de un arreglo se pueden llenar de varias formas, como por ejemplo:  Desde la declaración del arreglo: int arre []={11,13,14,5,1,10,12};  Pidiéndole al usuario los datos: arre[1]=lectura.nextInt(); //donde lectura es una variable de tipo Scanner  Desde un archivo: esta forma tiene la ventaja que se pueden llenar arreglos (de tamaño considerable) al inicio de la ejecución del programa y trabajar con ellos, sin tener que estar pidiéndole al usuario que los introduzca cada vez que quiera iniciar el programa. En la etapa de pruebas ésta forma es sumamente útil. Para poder trabajar con archivos, en Java, se deben importar las librerías de java.io.* y java.util.Scanner, las cuales nos permiten trabajar con la clase File para manejo de archivos y con la clase Scanner que se utiliza para obtener datos desde diferentes fuentes, como el teclado o en este caso un archivo. Cuando se trabaja con archivos es necesario recordar que Java pide explícitamente el control de excepciones a través de la sentencia try { } catch{ }, ya que se pueden presentar errores (excepciones) en tiempo de ejecución, como que el archivo no se encuentre, no se indique correctamente el nombre, o el tipo, etc. Esta estructura nos permite ejecutar una serie de líneas de código previendo que se cometa algún error. En caso de que no ocurran errores se seguirá con el código especificado en la parte del Try, si se comete el error (ocurrencia de la excepción) estipulado en el catch, entonces se ejecutan las instrucciones de su bloque. La lectura del archivo es similar a la lectura de datos desde consola (datos proporcionados por un usuario), se utilizan de la clase Scanner los mismos métodos .next(), .nextInt() o .nextDouble() dependiendo del tipo de información que tenga el archivo. A continuación se explica, a través de un ejemplo, como leer datos de un archivo y almacenarlos en un arreglo. Ejemplo: Se desea crear una clase EjemploArchivos con métodos estáticos y un método main, que nos permita leer números de un archivo “datos.txt”, guardarlos en un arreglo de doubles, de un tamaño definido (el tamaño del arreglo está dado como primer dato en el archivo de texto) e imprimir el contenido del arreglo. Solución: Se crea en Eclipse un Java Project llamado LecturaArchivoYArreglos, en el cual se crea la clase EjemploArchivos. Para poder trabajar con archivos es conveniente crear primero el archivo con los datos, este debe ser de tipo .txt (para que NO almacene formatos) y debe estar guardado (por simplicidad) en la carpeta del proyecto donde se guarda la clase que lo va a leer (al mismo nivel que la carpeta src). Es importante tener en consideración como se construye el archivo y el orden de los elementos según su tipo, para que a la hora que se haga el código exista una correspondencia entre cómo están los datos y cómo se quieren leer. Apuntes Algoritmos y Programas

62


Instituto Tecnológico Autónomo de México

El archivo de texto quedaría así: Tamaño de arreglo

El archivo muestra en la primera línea un 10 que es el número de elementos del arreglo y en los siguientes renglones muestra los 10 datos a almacenar en el arreglo de doubles. Realmente no es muy importante la cantidad de espacios que se le dé entre los números, ya que cuando se leen números, los espacios se saltan, se ignoran, es decir, es lo mismo tener como separador un espacio, varios espacios, un tabulador, o un <enter>. Para los Strings si es importante el número de espacios o <enter>’s en la lectura. A continuación se muestra el lugar donde está almacenado el archivo:

A continuación se muestra el programa en Java, a través del código están escritas las explicaciones como comentarios. //Se importan las librerías con las clases a utilizar import java.io.*; import java.util.Scanner; public class EjemploArchivos { //se crea un método estático para imprimir los elementos de un arreglo public static void imprimeArreglo(double[] arre){ int n; n=arre.length; for(int i=0;i<n;i++) Apuntes Algoritmos y Programas

63


Instituto Tecnológico Autónomo de México

System.out.println("el dato : "+i+" es: "+ arre[i]); } public static void main(String[] args) { //Se declara el arreglo // y se declara una variable para almacenar el número de // elementos del arreglo double []numeros; int n; //Se declara un objeto de la clase File // y un objeto de la clase Scanner para la lectura del //archivo. File entrada; Scanner lectArch; //Se instancia el objeto entrada de la clase File //dándole como parámetro el nombre del archivo de texto // que contiene los datos a leer. entrada = new File("datos.txt"); // Se pone la estructura Try, catch para el manejo de // excepciones try{ // este código se ejecutará mientras no existan //excepciones /* se instancia el objeto de la clase Scanner * asociándolo con el objeto de la clase File, * de esta manera se indica que las lecturas se * realizarán a través del archivo de nombre dato.txt*/ lectArch = new Scanner(entrada); /* Se comienza con la lectura del archivo y * se instancia el arreglo con el primer dato leído. * Los elementos se toman en el orden en el que * aparecen en el archivo */ n= lectArch.nextInt(); numeros= new double[n]; //ciclo for para el llenado del arreglo Apuntes Algoritmos y Programas

64


Instituto Tecnológico Autónomo de México

for(int i=0;i<n;i++) numeros[i]=lectArch.nextDouble(); /* Cuando se termina la lectura es importante cerrar el * archivo, de esta manera se indica que ya no se va * usar más */ lectArch.close(); System.out.println("\nArreglo: "); //se imprime el arreglo utilizando el método arriba //definido imprimeArreglo(numeros); }

catch (Exception e){ //imprime un mensaje de error de acuerdo a la excepción // presentada System.out.println(e.getMessage()); } } } Resultado

Apuntes Algoritmos y Programas

65


Instituto Tecnológico Autónomo de México

13.

Manejo de listas en Java con ArrayList

Una lista es una estructura de datos para almacenar varios datos del mismo tipo bajo un solo nombre. A diferencia de los arreglos, las listas son dinámicas, es decir, su tamaño puede variar en el curso de la ejecución de un programa, por lo que normalmente se utilizan cuando no sabemos de antemano cuantos elementos deseamos almacenar. En Java las listas se pueden manejar con la clase ArrayList, que ya cuenta con una serie de métodos y funciones que permiten el manejo de la lista sin tener que crearlos de manera propia. Esta clase aumenta su capacidad por sí sola, es decir, aparentemente siempre tiene capacidad para agregar nuevos elementos a la lista, por lo que NO es necesario especificar el límite de elementos que puede contener en el momento de crear una instancia, ya que esta irá creciendo conforme se necesite. Es importante tener en cuenta que el primer elemento del ArrayList tiene como índice 0. Dentro de sus métodos y/o funciones se encuentran:  ArrayList.add: agrega un elemento.  ArrayList.remove: elimina un elemento.  ArrayList.size: arroja el número de elementos que contiene la lista.  ArrayList.clear: limpia la lista, la deja vacía.  ArrayList.toString: regresa en un String los elementos de la lista. La sintaxis general de declaración y para crear una instancia (con constructor nulo) de un objeto de la clase ArrayList es la siguiente: ArrayList <Tipo> nombreLista; nombreLista= new ArrayList <Tipo> (); Los tipos de las lista deben de ser una clase, por lo que no se pueden utilizar tipos primitivos como char, int o double. En caso de que se desee tener un ArrayList de enteros se debe de poner el nombre completo de la clase Integer, por ejemplo: ArrayList <Integer> listaDeEnteros; listaDeEnteros= new ArrayList <Integer> (); Ejemplo: Supongamos que tenemos un arreglo de 15 números y se desea generar una lista (ArrayList) que contenga solamente los números mayores que 10 que se encuentren en el arreglo. Se realizará una función cuyo objetivo sea crear una lista con los números que cumplan con la condición antes mencionada, del arreglo que le demos como parámetros. Hay que recorrer todos los elementos del arreglo para que llene la lista con un ciclo for. Como se puede observar, nuestro método regresará un ArrayList de tipo Integer. public static ArrayList<Integer> mayoresDiez(Integer [] arre){ // se declara e instancia la lista ArrayList <Integer> lista; lista =new ArrayList<Integer>(); int n; n=arre .length; //se obtiene el número de elementos del arreglo Apuntes Algoritmos y Programas

66


Instituto Tecnológico Autónomo de México

//se revisa uno a uno los elementos del arreglo for(int i=0; i<n; i++) //si el elemento del arreglo es mayor a 10, se agrega a la lista if(arre[i]>10) lista.add(arre[i]); return lista; } Para verificar que el código realizado funciona correctamente haremos un método main y crearemos un arreglo para después invocar al método mayoresDiez. public static void main(String[] args) { /*creación del arreglo, nótese que se puede crear un arreglo indicando directamente sus elementos También el tipo del arreglo es Integer ya que la lista sólo acepta tipos de una clase*/ Integer arre []={11,13,14,5,1,10,12}; //se declara la lista donde quedará el resultado que arroje el método ArrayList<Integer> lista; //se asigna a la lista el resultado de la invocación al método mayoresDiez lista=mayoresDiez(arre); //se imprime la lista resultado System.out.println(lista.toString()); }

Apuntes Algoritmos y Programas

67


Instituto Tecnológico Autónomo de México

14.

Interfaces gráficas en Java

La interfaz gráfica de usuario GUI es la parte del programa que permite presentar al usuario información y que este opere las funciones del programa de una manera más sencilla y amigable utilizando ventanas, botones, imágenes, gráficos, etc. Para efectos de este curso utilizaremos el patrón modelo-vista-controlador MVC, con el objetivo de separar las reglas del negocio de la presentación, y esta presentación la separaremos en la parte visual gráfica de la parte de acceso a datos y funcionalidad misma de la ventana. Esta separación es conveniente ya que las reglas de negocio no deben alterarse por cómo le presentemos al usuario la información, y en la parte de presentación debemos separar la parte visual y gráfica de la parte de acceso a funcionalidad y datos, para mejorar el desarrollo y mantenimiento de la aplicación. Entonces las interfaces graficas en Java las manejaremos en dos partes: una vista y un controlador. La vista es la clase que contiene los objetos gráficos de la interfaz (como podría ser la ventana del programa, una caja de texto, un botón, imágenes, etc.) y el controlador es la clase que le da una funcionalidad específica a cada elemento contenido en la vista. Como ejemplo para la parte vista-controlador, se creará un programa con interfaz gráfica que pueda convertir de kilómetros a millas y viceversa. La clase de la vista se llamará ConvertidorVista y el controlador se llamará ConvertidorControlador.

14.1.

Vista

Primeramente, se inicia con la vista ya que le dará forma al programa y es el prototipo del mismo, por así llamarle. Al crear la vista se deben de importar las siguientes clases: import javax.swing.*; import javax.swing.border.Border; import java.awt.GridLayout; De estas clases importadas obtendremos todos los elementos necesarios para declarar, instanciar e inicializar los objetos de las interfaces gráficas de Java. Además, la clase debe de extenderse de la clase Jframe, esto significa que se crea una relación de herencia entre las dos clases. El JFrame es la clase madre y nuestra clase de la vista es la clase hija. public class ConvertidorVista extends JFrame{ Al extender la clase podemos acceder a los métodos y atributos de la clase JFrame y utilizarlos de acuerdo al problema a resolver. Como cualquier otra clase, la clase Vista tendrá atributos. Dentro de esta sección se pondrán los elementos que tendrá nuestra vista, que serán los elementos que queremos que vea el usuario en la ventana, se pueden agregar objetos como botones, etiquetas, cajas de texto, etc. Lista de algunos componentes GUI’s en Java:  JLabel: este elemento sirve para desplegar texto como si fuera una etiqueta. Es útil para nombrar algo o hacer un título dentro de la vista.  JTextField: consiste en una caja de texto donde se puede desplegar información y el usuario puede escribir sobre él.  JTextArea: es similar al JtextField pero con más de un renglón para la escritura. Apuntes Algoritmos y Programas

68


Instituto Tecnológico Autónomo de México

JButton: como su nombre se indica, es un botón que sirve para llamar alguna acción del programa, se le puede agregar un texto para describir su función. Antes de programar una vista es conveniente hacer un dibujo de cómo queremos que se vea la ventana de la aplicación para decidir qué elementos debemos incluir y el orden de los mismos. Para hacer el convertidor necesitamos una ventana como esta:

Entonces los atributos necesarios en la clase ConvertidorVista quedarían así: private static final long serialVersionUID= 1L; protected JTextField kilometros,millas; private JLabel km,mi; El atributo serialVersionUID es un atributo final (constante) y estático (único por clase, no lo tienen los objetos) que se utiliza para que nuestra vista no se preocupe por la serialización que manejan los JFrames (es una clase serializable por definición), basta decir que equivale, de manera muy simplista, al número de versión de la ventana, no se explicará más este tema ya que queda fuera del ámbito del curso. El encapsulamiento de los atributos depende de cómo se vayan a usar. En caso de que el usuario interactúe con el elemento, se especificará como protected ya que así la clase Controlador podrá tener acceso a él. En el caso de que sólo muestre información se pondrá como private ya que no queremos que el usuario, a través del controlador, tenga acceso a ellos. En nuestro código tenemos al JTextField como protected ya que el usuario escribirá en él y el controlador deberá responder a ello, si fuese un botón el caso sería similar, ya que el usuario le dará clic para pedir una acción. Mientras tanto los JLabel son private porque no es necesario que el usuario interactúe con ellos (y en consecuencia el controlador no deberá ejecutar acción alguna relacionada con ellos). Después se prosigue con la construcción de la vista, que se extiende (es subclase) de la clase JFrame, en el constructor de la vista se debe de añadir el llamado al constructor del JFrame que “hace” la ventana, esto se hace con el llamado super(), este constructor sólo nos pide un String que será el título de nuestra ventana. //constructor public ConvertidorVista (String titulo){ super (titulo);

Apuntes Algoritmos y Programas

69


Instituto Tecnológico Autónomo de México

Se continúa con la instanciación de los atributos de la vista, que serán los elementos de la ventana. Como se puede observar, cada tipo de elemento se instancia de manera diferente. El JTextField lo hace con la indicación de su longitud tomando un cierto número de caracteres como referencia. Mientras tanto, el JLabel recibe inmediatamente el texto que mostrará al usuario. Estos sólo son una parte de los constructores que poseen algunos elementos, pero hay muchos más que se pueden consultar en los API’s de Java. //creacion de los componentes kilometros= new JTextField(16); millas= new JTextField(16); km= new JLabel("Kilometros"); mi= new JLabel("Millas"); Adicionalmente, en esta sección se construye el JPanel. El JPanel es el lugar donde se colocarán todos los elementos de la vista, trabaja como el contenedor de la ventana. Se le asignará al JPanel un orden de cuadrícula, es decir, los elementos se acomodarán según las filas y columnas que se decidan. Se crea también un borde para dejar espacios vacíos arriba, izquierda, abajo y derecha del panel. Hay que agregar al JPanel los elementos creados con la instrucción add(), conforme los añadimos estaremos indicando como estarán colocados en la cuadrícula y se colocan de izquierda a derecha y de arriba abajo por omisión (a menos que se cambie la orientación del gridlayout). Al terminar de agregar los elementos se añade la instrucción add() con el nombre de nuestro panel para añadir el panel a la ventana. //crear el panel JPanel p= new JPanel(); //acomodar de los componentes (renglones, columnas) p.setLayout(new GridLayout(4,1)); Border gap=BorderFactory.createEmptyBorder(5,5,5,5); p.setBorder(gap); p.add(km); p.add(kilometros); p.add(mi); p.add(millas); add(p); // equivalente a this.add(p), se agrega el JPanel en el JFrame Por último, se da la posición y el tamaño de la ventana, en píxeles por lo que se puede cambiar el valor hasta que se obtenga el efecto deseado. También se indica la operación que se debe realizar al cerrar la ventana y se pone nuestra clase vista como visible. //posicion de la ventana //(sitio x,sitio y,dimensión x,dimensión y) setBounds(500,200,300,300); //acción al apretar cerrar setDefaultCloseOperation(EXIT_ON_CLOSE); Apuntes Algoritmos y Programas

70


Instituto Tecnológico Autónomo de México

}

//para que se vea la pantalla setVisible(true); //fin del constructor de la clase Vista

} Es conveniente saber el aspecto real de nuestra vista sin hacer aun la clase controlador, para ver si está como lo planeamos al inicio, para esto hay que agregar un método main que permita instanciar nuestra clase vista, que se cree la ventana y hacer una visualización de lo antes programado y así cambiar los valores de los elementos según se necesite. public static void main(String[] args) { ConvertidorVista ejemplo= new ConvertidorVista("Ejemplo de Vista"); } La vista se vería de la siguiente manera Títul o JLab el JTextFiel d JLab el JTextFiel d

14.2.

Controlador

Como se mencionó anteriormente, el controlador será la clase que permita que la vista tenga alguna funcionalidad ya que lo único que se ha hecho es el “esqueleto” de la ventana (solo un dibujo). Esta clase también necesita importar otras clases de java. Las clases ActionListener y ActionEvent que se encargan de detectar una acción (como un clic, escribir, mover, etc.) en algún elemento de la ventana y de dar una respuesta a la misma. import java.awt.event.ActionListener; import java.awt.event.ActionEvent; Para que la clase pueda tomar como referencia la vista que se creó se usa el extends, de esta manera la clase Controlador hereda de la clase Vista todos los elementos visuales ya definidos, la clase Controlador es una subclase de la clase Vista. public class ConvertidorControlador extends ConvertidorVista{ private static final long serialVersionUID= 1L; Apuntes Algoritmos y Programas

71


Instituto Tecnológico Autónomo de México

En el constructor del Controlador es sumamente importe no olvidar, que hay que poner el llamado al constructor de nuestra Vista y poner los “escuchas” de los objetos que necesitemos, como se explica a continuación:  Como el controlador se extiende de la vista, también se usa un super() con la misma variable String, que manda llamar al constructor de la Vista que a su vez manda llamar al constructor de la clase JFrame.  En los componentes JTextField que se heredan de la Vista, y que serán los elementos a los que se desea reaccionar con una acción, se les agrega el método addActionListener. Este método es un “escuchador”, es decir, siempre está a la espera de que se haga alguna acción sobre el objeto que lo contiene. //instanciacion del controlador public ConvertidorControlador(String nombre){ super(nombre); kilometros.addActionListener(new EscuchaKilometros()); millas.addActionListener(new EscuchaMillas()); } Cada addActionListener tiene una clase escuchador como parámetro EscuchaKilometros y EscuchaMillas, que hasta el momento no hemos puesto, no existen, por lo que se tienen que declarar en el mismo código del Controlador, antes del llamado, como clases internas por facilidad de manejo, ya que al declararlas así tenemos acceso a los elementos que tiene el Controlador. Estas clases son las que realmente le dan la funcionalidad a los elementos que interactúan con el usuario. Los “escuchas” deben tener implementado un método ActionPerformed, porque cuando se suscita una actividad en ellos, el escucha busca por default este método y es en este método donde codificamos la funcionalidad que deseamos tenga el elemento. La clase escucha debe indicar explícitamente que está implementando el método actionPerformed de la interfaz ActionListener. //se pone un implements con el ActionListener private class EscuchaKilometros implements ActionListener{ //Se crea el método que detecta la acción y realiza una respuesta public void actionPerformed(ActionEvent ae){ final double FACTOR =1.069344; String txtKm; String txtMi= ""; //se llama el método .getText() del JTextField txtKm= kilometros.getText(); if(!txtKm.equals("")){ double miDouble= Double.parseDouble(txtKm); miDouble /= FACTOR; Apuntes Algoritmos y Programas

72


Instituto Tecnológico Autónomo de México

txtMi= txtMi+ miDouble; //se le asigna el resultado al JTextField millas.setText(txtMi); } } } private class EscuchaMillas implements ActionListener{ public void actionPerformed(ActionEvent ae){ final double FACTOR =0.6217; String txtMi; String txtKm= ""; txtMi= millas.getText(); if(!txtMi.equals("")){ double miDouble= Double.parseDouble(txtMi); miDouble /= FACTOR; txtKm= txtKm+ miDouble; kilometros.setText(txtKm); } } } Las funciones getText() sirven para recuperar el texto escrito por el usuario en el JtextField, al cual el usuario dio un <enter>, como ya se mencionó anteriormente las funciones get sirven para recuperar el valor de un atributo, entonces nuestras cajas de texto tienen un atributo llamado text y con esta función podemos recuperar lo que el usuario escribió y el objeto almacenó en dicho atributo. Nótese que lo que guarda la caja de texto es siempre un texto, es decir, aun cuando el usuario teclee un número este se verá como texto, sin valor numérico. Después se verifica que haya algo en el campo de texto, en caso afirmativo se convierte ese texto a un número double, se hace la operación y finalmente se exhibe el resultado a través del setText de la caja de texto contraria, ahora se cambia el valor del atributo text. Al final del código se debe colocar el método main, de esta manera se instancia el controlador, que instancia la vista y se tiene la funcionalidad completa del programa. public static void main(String[] args) { new ConvertidorControlador("Ejemplo de Vista"); } }

La funcionalidad de nuestro programa queda de la siguiente manera  Se escribe la cantidad de kilómetros o millas a convertir Apuntes Algoritmos y Programas

73


Instituto Tecnológico Autónomo de México

  

Para que el programa detecte nuestra información damos un enter, esto causa un cambio de línea y el escuchador se activa. Se ejecuta lo programado en el método actionPerformed correspondiente. En la casilla contraria se ve el resultado convertido.

Se inserta el dato y se presiona “ENTER”

Apuntes Algoritmos y Programas

74


Instituto Tecnológico Autónomo de México

15.

Ejecutar un programa en Java fuera de un IDE

Es importante recordar que Java es un lenguaje de programación que puede ser utilizado a través de varios ambientes de desarrollo o IDE’s, pero también se puede escribir un programa en el block de notas y ejecutarlo directamente. Esto no es muy común ya que perdemos todas las ventajas de los IDE’s, como corrección de ortografía, pero es importante señalar la independencia del código en Java con el IDE de desarrollo. Por ejemplo si escribimos el típico programa Hola Mundo en Java, tendremos el siguiente código: public class Holamundo { public static void main(String[] args) { System.out.println("¡¡¡¡¡¡ Hola Mundo !!!!!!"); } } El archivo debe ser almacenado en la ruta deseada, como por ejemplo: C\ejemplo, con el nombre (igual a la Clase) Holamundo.java, para guardar un archivo en el block de notas con otra extensión (no .txt) se debe poner todo el nombre entre comillas al guardarlo.

Una vez almacenado el programa se debe compilar y ejecutar para ver los resultados, pero no vamos a utilizar algún ambiente de desarrollo, sino que lo vamos a correr directo desde el sistema operativo. Para esto se debe abrir una ventana DOS, está en inicio -> ejecutar y se teclea CMD, esto abre una ventana del Disc Operating System DOS y aparece un prompt > indicando que espera un comando. Desde aquí dando instrucciones directas al sistema operativo debemos compilar y ejecutar nuestro programa.

Apuntes Algoritmos y Programas

75


Instituto Tecnológico Autónomo de México

Antes de hacerlo hay que verificar que el sistema operativo tenga en el path, la ruta adecuada para poder compilar y correr el programa en Java. Path es una variable de entorno del sistema operativo que contiene las rutas de búsqueda de programas, por lo que debe contener la ruta donde se encuentra javac.exe y java.exe, que son los programas que se encargan de compilar y ejecutar programas en Java respectivamente. Para saber que contiene el path se teclea simplemente path y el sistema mostrará las rutas almacenadas separadas por ;.

Si después de revisarlo se verifica que no está, se puede añadir con la siguiente instrucción: path=%path%; c:\ y la ruta donde se encuentran en nuestra computadora Esta ruta es donde normalmente se encuentra el JDK en nuestra máquina Esta instrucción cambiará el path sólo durante la sesión DOS que abrimos, cuando la cerremos NO guarda los cambios. Después hay que cambiarse de directorio al que contiene el archivo que deseamos compilar con la instrucción: Apuntes Algoritmos y Programas

76


Instituto Tecnológico Autónomo de México

cd nueva ruta ejemplo: cd c:\ejemplo Una vez posicionados en el directorio que contiene el archivo podemos dar la instrucción dir para verificar que si estamos “situados” en el directorio adecuado. Después para compilar el programa se debe teclear la instrucción: javac nombreArchivo.java Ejemplo: javac Holamundo.java Si existen errores de compilación, el compilador los marca y deben ser corregidos en el archivo, guardarlo y volver a compilar, así hasta que ya no marque errores. Cuando ya no marca errores la compilación crea un archivo con el mismo nombre del original pero con la extensión .class, podemos verificarlo dando la instrucción dir. Para ejecutar el programa se debe dar la instrucción: java nombreArchivo sin extensión ejemplo: java Holamundo Entonces mostrará el recadito de ¡¡¡¡¡¡ Hola mundo !!!!! Para salir del DOS se debe dar el comando exit. La siguiente imagen muestra de forma gráfica los pasos explicados anteriormente:

Apuntes Algoritmos y Programas

77


Instituto Tecnológico Autónomo de México

16.

Consulta de API’s en Java

Las interfaces de programación de aplicaciones Application Programming Interface API’s, por sus siglas en inglés, son como su nombre lo indica, interfaces que proveen todas las funciones y métodos que contienen las clases y que podemos consultar para utilizarlas en nuestros programas. Hay que recordar que Java ya tiene programadas muchas clases con su funcionalidad y que podemos utilizarlas, facilitándonos muchas tareas. Estas API’s pueden ser consultadas en libros o en internet, en internet existe Java 6 Estándar Edition Documentation que contiene la explicación de estas API’s, o se puede teclear en un buscador la clase que se desea consultar, como por ejemplo Scanner y de ahí seleccionar la liga de las API docs, la cual nos mostrará la siguiente ventana:

En la primera parte muestra una explicación de la clase y más abajo muestra sus métodos y funciones, indicando para cada uno qué parámetros necesita y qué tipo de dato regresan las funciones, esta información es sumamente útil cuando queremos utilizar correctamente lo que Java ya tiene programado.

Apuntes Algoritmos y Programas

78


Instituto Tecnológico Autónomo de México

Todas las clases tienen ligas a sus propias API’s, si se selecciona String nos llevara a la documentación de la clase String y así podemos hacer las consultas necesarias:

Apuntes Algoritmos y Programas

79


Instituto Tecnológico Autónomo de México

17.

Generación automática de documentación

Java tiene la facultad de ayudarnos con la documentación de los programas construyendo las API’s de nuestros proyectos a través del JavaDoc.exe. Dentro del código se pueden escribir comentarios que reconoce el JavaDoc y que se incluyen dentro de las API’s, los cuales deben cumplir con ciertas condiciones:  Empiezan con /** y terminan con */, pudiendo tener más de una línea.  Para comentarios de la clase, deben estar escritos antes de la declaración de la clase.  Los comentarios internos, deben estar escritos fuera del método o función que quieren explicar, inmediatamente anterior a la declaración del mismo. Estos comentarios pueden ser libres, pero JavaDoc tiene ya una estructura fija para cierto tipo de comentarios que comienza con una @ y que son utilizados como indicadores especiales en el documento, los más usados son:  @author nombreDelAutor se utiliza para indicar el nombre del creador del código.  @version numeroDeVersion se debe indicar la versión de la clase en cuestión.  @param descripción se utiliza para dar una explicación de los parámetros de un método o función.  @return descripción explica en qué consiste el valor que regresa la función.  @see descripción se utiliza cuando se quiere hacer referencia a otra clase o método.  @throws descripción se debe explicar qué tipo de excepción puede manejar el método o función en cuestión. A continuación se muestran dos secciones del código de una clase Zoologico con comentarios insertados para el JavaDoc, el primero para hacer comentarios sobre la clase en sí y el segundo hace comentarios sobre una función en particular: /** @author Juan Perez * 07/05/12 * Ejercicio para segundo examen parcial */ public class Zoologico { private String nombre; private String direccion; private final int TOT=20; private Animal animales[]; ………. ………. /** Método para encontrar el número de animales de cierta raza * @author Administrador * @return regresa el número de animales encontrados en el arreglo que pertenecen a la raza unaRaza */ Apuntes Algoritmos y Programas

80


Instituto Tecnológico Autónomo de México

public int cuantosPorRaza(String unaRaza){ int i, tot; tot=0; for(i=0;i<TOT;i++) if(animales[i].getRaza().compareTo(unaRaza)==0) tot++; return tot; } Estos comentarios los podemos ir insertando en el código conforme desarrollemos nuestra aplicación. Una vez terminada nuestra aplicación y que estamos seguros de que todo corre y funciona perfectamente bien, podemos crear la documentación usando el JavaDoc, antes no, ya que no tiene sentido crear documentación de algo que No sirve. En Eclipse se selecciona el proyecto del cual queremos la documentación en el explorador de paquetes, se selecciona del menú Project->Generate JavaDoc, entonces se abre una ventana con el asistente para crear la documentación:

Debe tener la dirección del JavaDoc

Se indican los paquetes de los cuales se quiere la documentación

Muestra el lugar donde se guardan los archivos generados

Se pone Finish y el asistente crea las API’s, en la dirección indicada crea un folder llamado Doc con los archivos HTML correspondientes. Para nuestro ejemplo de la clase Zoologico crea el siguiente documento:

Apuntes Algoritmos y Programas

81


Instituto Tecnológico Autónomo de México

Package Class Use Tree Deprecated Index Help PREV CLASS NEXT CLASS SUMMARY: NESTED | FIELD | CONSTR | METHOD

FRAMES NO FRAMES All Classes DETAIL: FIELD | CONSTR | METHOD

Class Zoologico java.lang.Object Zoologico public class Zoologico extends java.lang.Object

Comentarios insertados

Author: Juan Perez 07/05/12 Ejercicio para segundo examen parcial

Constructor Summary Zoologico(java.lang.String direccion, java.lang.String nombre)

Method Summary int cuantosPorRaza(java.lang.String unaRaza)

Método para encontrar el número de animales de cierta raza java.lang.String getDireccion() java.lang.String getNombre()

Comentarios insertados

double promEdades() boolean setUnAnimal(java.lang.String nombre, int edad, java.lang.String raza, int pos)

Methods inherited from class java.lang.Object equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail Zoologico public Zoologico(java.lang.String direccion, java.lang.String nombre)

Method Detail getNombre

public java.lang.String getNombre()

Apuntes Algoritmos y Programas

82


Instituto Tecnológico Autónomo de México

getDireccion public java.lang.String getDireccion()

setUnAnimal public boolean setUnAnimal(java.lang.String nombre, int edad, java.lang.String raza, int pos)

cuantosPorRaza

public int cuantosPorRaza(java.lang.String unaRaza)

Comentarios insertados

Método para encontrar el número de animales de cierta raza Returns: regresa el número de animales encontrados en el arreglo que pertenecen a la raza unaRaza promEdades public double promEdades()

Package Class Use Tree Deprecated Index Help PREV CLASS NEXT CLASS SUMMARY: NESTED | FIELD | CONSTR | METHOD

FRAMES NO FRAMES All Classes DETAIL: FIELD | CONSTR | METHOD

Este documento generado sigue la estructura general de las API’s, si son varias clases se puede generar el índice y el árbol de referencia de las mismas, eligiendo varias opciones en el asistente de la documentación. Cabe recordar la importancia de documentar adecuadamente una aplicación, ya que por muy bien hecha que esté, con el tiempo es muy probable que tengan que hacérsele cambios, por lo que la documentación se vuelve esencial para las actualizaciones y adecuaciones de los programas.

Apuntes Algoritmos y Programas

83


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.