Sei sulla pagina 1di 18

PROGRAMACIÓN BÁSICA

Unidad 4: Modularización
Bienvenido a la ​unidad 4 de Programación Básica​, al finalizar el estudio de esta unidad tendrás un
conocimiento y adquirirás habilidades de los siguientes temas:

● Subrutinas, definición y ventajas de su uso. Métodos.

● Mecanismos de paso de parámetros.

● Utilización de librerías.

● Introducción y aplicación de algunos conceptos de ingeniería


de software como generalización, parametrización y
reusabilidad.

Introducción
En la primera unidad hemos visto que los algoritmos están presentes en todas nuestras acciones.
Aplicamos algoritmos para resolver situaciones cotidianas tales como cruzar una calle, preparar una
taza de té o leer un libro.

Si prestamos atención a los pasos que seguimos cuando, por ejemplo, preparamos una taza de té
naturalmente llegaremos a la siguiente enumeración:
1. Ir a la cocina
2. Calentar agua
3. Preparar la taza
4. Poner el agua en la taza

Sabemos también que “ir a la cocina” implica “caminar”, y “caminar” implica “dar un paso tras otro”
y “dar un paso” implica “levantar, adelantar y bajar un pie”, “levantar el pie” implica “tensionar un
conjunto de músculos”, etcétera.

Pensemos ahora este mismo algoritmo al revés, analizando desde la acción más particular hasta
llegar a la acción más general. Tendríamos que “tensionar los músculos” para “levantar un pie” para
“dar un paso” para “ir a la cocina”. Sería verdaderamente enloquecedor e impracticable.

1 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Conceptos iniciales
Metodología top-down
La ​metodología top-down ​propone pensar la solución de un problema en base a una secuencia de
acciones de nivel general cuyos pasos iremos refinando sucesivamente.

Esto significa partir de un análisis global y refinarlo hasta llegar a un análisis particular. Aplicando
esta metodología a la resolución de problemas computacionales podremos resolver situaciones
complejas con una simpleza y naturalidad verdaderamente sorprendente.

Módulos o subprogramas
Llamamos “módulo”, “rutina” o “subprograma” a cada una de las acciones que ejecutamos en
nuestro algoritmo y que luego vamos a desarrollar.

En el ejemplo de ​preparar una taza de té​, invocamos a los módulos “caminar hacia la cocina”,
“calentar el agua”, etc. Luego tendremos que desarrollar cada uno de estos módulos para los cuales,
probablemente, necesitemos invocar a otros módulos que también tendremos que desarrollar.

Módulos de programas en Java


Existen tres tipos de módulos en Java: métodos, clases y paquetes. Para escribir programas en Java,
se combinan los nuevos métodos y clases que uno escribe con los métodos y clases predefinidos,
que están disponibles en la Interfaz de Programación de Aplicaciones de Java (también conocida
como la API de Java o biblioteca de clases de Java) y en diversas bibliotecas de clases. Por lo general,
las clases relacionadas están agrupadas en paquetes, de manera que se pueden importar a los
programas y reutilizarse. La API de Java proporciona una vasta colección de clases que contienen
métodos para realizar cálculos matemáticos, manipulaciones de cadenas, manipulaciones de
caracteres, operaciones de entrada/salida, comprobación de errores y muchas otras operaciones
útiles.

Procurá familiarizarte con la vasta colección de clases y métodos que proporciona la API de Java
(​https://docs.oracle.com/javase/7/docs/api/​) y evita reinventar la rueda. Cuando sea posible,
reutiliza las clases y métodos de la API de Java. Esto reduce el tiempo de desarrollo de los programas
y evita que se introduzcan errores de programación​.

Métodos de la clase Math


En matemática, probablemente hayas visto funciones como ​sin ​y ​log​. Java provee un conjunto de
funciones pre incorporadas que incluye la mayoría de las operaciones matemáticas que puedas

2 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
imaginar. Estas funciones son llamadas ​métodos​. La mayoría de los métodos matemáticos operan
con ​doubles​.

Los métodos matemáticos son llamados usando una sintaxis que es similar a la de los método print
que ya hemos visto:

double raiz = Math.sqrt (17.0);


double angulo = 1.5;
double altura = Math.sin (angulo);

El primer ejemplo asigna a ​raiz la raíz cuadrada de 17. El segundo ejemplo encuentra el seno de
1.5, el cual es el valor de la variable ​angulo​. Java asume que los valores que usás con sin y las otras
funciones trigonométricas (cos, tan) están en radianes. Una forma de convertir de grados a radianes,
es dividir por 360 y multiplicar por 2. Convenientemente, Java provee a como valor preincorporado:

double grados = 90;


double angulo = grados * 2 * Math.PI / 360.0;

Notar que ​PI​ está todo en letras mayúsculas. Java no reconoce Pi, pi, ni pie.
Otro método útil en la clase Math es round (redondear), el cual redondea un valor de punto flotante
al entero más cercano y devuelve un int.

int x = Math.round (Math.PI * 20.0);

En este caso la multiplicación sucede primero, antes de que el método sea llamado. El resultado es
63 (redondeado hacia arriba desde 62.8319).

A continuación se sintetizan varios de los métodos de la clase ​Math ​y donde ​x y ​y son de tipo
double.

3 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Los ​métodos ​(también conocidos como funciones o procedimientos en otros lenguajes) permiten al
programador dividir un programa en módulos, por medio de la separación de sus tareas en unidades
autónomas. Los métodos que fuiste declarando en todos los programas se dice que son métodos
declarados por el programador. Las instrucciones en los cuerpos de los métodos se escriben sólo una
vez, y se reutilizan tal vez desde varias ubicaciones en un programa; además, están ocultas de otros
métodos.

Una razón para dividir un programa en módulos mediante los métodos es la metodología “​divide y
vencerás”, que hace que el desarrollo de programas sea más fácil de administrar, ya que se pueden
construir programas a partir de piezas pequeñas y simples. Otra razón es la reutilización de software
(usar los métodos existentes como bloques de construcción para crear nuevos programas). A
menudo se pueden crear programas a partir de métodos estandarizados, en vez de tener que crear
código personalizado. Por ejemplo, en los programas anteriores no tuvimos que definir cómo leer los
valores de datos del teclado; Java proporciona estas herramientas en la clase ​Scanner​. Una tercera
razón es para evitar la repetición de código. El proceso de dividir un programa en métodos
significativos hace que el programa sea más fácil de depurar y mantener.

4 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Para promover la reutilización de software, cada método debe limitarse de manera que realice una
sola tarea bien definida, y su nombre debe expresar esa tarea con efectividad. Estos métodos
hacen que los programas sean más fáciles de escribir, depurar, mantener y modificar.

Un método se invoca mediante una llamada, y cuando el método que se llamó completa su tarea,
devuelve un resultado, o simplemente el control al método que lo llamó. Una analogía a esta
estructura de programa es la forma jerárquica de la administración . Un jefe (el solicitante) pide a un
trabajador (el método llamado) que realice una tarea y que le reporte (devuelva) los resultados
después de completar la tarea. El método jefe, no sabe cómo el método trabajador, realiza sus
tareas designadas. Tal vez el trabajador llame a otros métodos trabajadores, sin que lo sepa el jefe.
Este “ocultamiento” de los detalles de implementación fomenta la buena ingeniería de software. La
figura siguiente muestra al método jefe comunicándose con varios métodos trabajadores en forma
jerárquica.

El método jefe divide las responsabilidades entre los diversos métodos trabajadores. Observá que
trabajador1 actúa como “método jefe” de trabajador4 y trabajador5.

Relación jerárquica entre el método jefe y los métodos trabajadores.

Interfaz y encapsulamiento
Para comprender mejor los conceptos de interfaz y encapsulamiento, podemos pensar, por ejemplo,
en un teléfono celular. El teléfono tiene los botones numéricos a través de los que podemos marcar
un número y luego dos botones: uno verde para establecer la llamada y uno rojo para cortar la
comunicación.

Con esto, a cualquier usuario común le resulta muy fácil manejar un teléfono celular ya que, usando
adecuadamente este conjunto de botones, puede marcar un número y luego establecer la
comunicación deseada.

5 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Obviamente, nadie, salvo un estudiante de ingeniería en comunicaciones, se preocupará por
entender el proceso que se origina dentro del teléfono luego de que presionamos el botón verde
para establecer la llamada. Simplemente, nos abstraemos del tema ya que ese no es nuestro
problema.

Decimos entonces que el conjunto de botones numéricos más los botones rojo y verde constituyen
la interfaz del objeto teléfono celular. El usuario (nosotros) interactúa con el objeto a través de su
interfaz y no debe abrir la carcasa del teléfono para ver ni mucho menos para tocar su
implementación (cables, chips, transistores, etc.).

Justamente, en el teléfono celular, los botones están expuestos y los componentes electrónicos son
internos y están protegidos (encapsulados) dentro de la carcasa para que nadie los pueda tocar.

Funciones y subprogramas
Cuando aplicamos algoritmos a la resolución de problemas computacionales los módulos se
implementan como funciones.

Una función es un subprograma invocado desde el programa principal (o desde otra función) que
ejecuta una tarea determinada y luego, retorna el control al programa o función que la invocó.

¿Por qué el método ​main​ se declara como static?


Cuando se ejecuta la Máquina Virtual de Java (JVM) con el comando java, la JVM trata de invocar al
método ​main de la clase que usted le especifica; cuando no se han creado objetos de esa clase. Al
declarar a main como ​static​, la JVM puede invocar a ​main sin tener que crear una instancia de la
clase. El método main se declara con el siguiente encabezado:

public static void main( String args[ ] )

Cuando ejecutás la aplicación, especificás el nombre de su clase como un argumento para el


comando
java, como sigue​ java NombreClase argumento1 argumento2 …

La JVM carga la clase especificada por ​NombreClase y utiliza el nombre de esa clase para invocar al
método ​main​. En el comando anterior, ​NombreClase es un argumento de línea de comandos para
la JVM, que le indica cuál clase debe ejecutar. Después del NombreClase, también puede especificar
una lista de objetos ​String (separados por espacios) como argumentos de línea de comandos, que

6 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
la JVM pasará a su aplicación. Dichos argumentos pueden utilizarse para especificar opciones (por
ejemplo, un nombre de archivo) para ejecutar la aplicación.

Como veremos en la próxima unidad, la aplicación puede acceder a esos argumentos de línea de
comandos y utilizarlos para personalizar la aplicación.

Comentarios adicionales acerca del método ​main


En los primeros programas que fuimos escribiendo, todas las aplicaciones tenían una clase que sólo
contenía a ​main​, y posiblemente una segunda clase que main utilizaba para crear y manipular
objetos.

En realidad, cualquier clase puede contener un método ​main​. De hecho, cada uno de nuestros
ejemplos con dos clases podría haberse implementado como una sola clase.

Se podría colocar un método ​main en cada clase que declare. La JVM invoca sólo al método ​main en
la clase que se utiliza para ejecutar la aplicación. Algunos programadores aprovechan esto para crear
un pequeño programa de prueba en cada clase que declaran.

Composición
Tal como con las funciones matemáticas, los métodos en Java pueden ser compuestos, lo cual
significa que es posible usar una expresión como parte de otra. Por ejemplo, es posible usar
cualquier expresión como argumento de un método:

double x = Math.cos (angulo + Math.PI/2);

Esta sentencia toma el valor ​Math.PI​, lo divide por dos y suma el resultado al valor de la variable
angulo​. La suma es entonces pasada como un argumento al método ​cos​. (Notar que ​PI es el
nombre de una variable, no un método, por lo que no hay argumentos, ni siquiera el argumento
vacío ()).
También podemos tomar el resultado de un método y pasarlo como argumento de otro:

double x = Math.exp (Math.log (10.0));

En Java, la función ​log siempre usa base e, por lo que esta sentencia encuentra el logaritmo en base
e​ de ​10​ y después eleva ​e​ a esa potencia. El resultado es asignado a ​x​; espero que sepas cuál es.

7 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Agregando nuevos métodos
Hasta ahora, sólo hemos estado usando los métodos que vienen preincorporados en Java, pero
también es posible agregar nuevos métodos. En realidad, ya hemos visto una definición de un
método: ​main1. El método llamado ​main es especial porque indica dónde empieza la ejecución de
un programa, pero la sintaxis de main es la misma que para cualquier definición de métodos:

public static void NOMBRE ( LISTA DE PARAMETROS ) {


SENTENCIAS
}

Podés inventar cualquier nombre que quieras para tu método, excepto que no podés llamarlo ​main
o alguna otra palabra reservada de Java. La lista de parámetros especifica qué información hay que
proveer, si es que la hay, para poder usar (o llamar) la nueva función.

El único parámetro de ​main es ​String[] args​, que indica que quienquiera que invoque a main
tiene que proveer un arreglo de Strings (nos detendremos en los arreglos en la unidad siguiente). Los
primeros dos métodos que vamos a escribir no tienen parámetros, por lo que la sintaxis se ve así:

public static void nuevaLinea () {


System.out.println ("");
}

Este método se llama ​nuevaLinea​, y los paréntesis vacíos indican que no toma parámetros.
Contiene solamente una única sentencia, que imprime una cadena vacía, indicada por "". Imprimir
un valor de tipo ​String sin ninguna letra puede no parecer útil, pero hay que recordar que
println saltea a la siguiente línea después de imprimir, por lo que esta sentencia tiene el efecto de
saltar a la línea siguiente.

En ​main podemos llamar a este nuevo método usando una sintaxis similar a la forma en que
llamamos a los comandos pre incorporados de Java:

public static void main (String[] args) {


System.out.println ("Primera linea.");
nuevaLinea ();

1
“principal” en inglés​.

8 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
System.out.println ("Segunda linea.");
}

La salida del programa es

Primera linea.
Segunda linea.

Notar el espacio extra entre las dos líneas. ¿Qué tal si quisiéramos más espacio entre las líneas?
Podríamos llamar al mismo método repetidamente:

public static void main (String[] args) {


System.out.println ("Primera linea.");
nuevaLinea ();
nuevaLinea ();
nuevaLinea ();
System.out.println ("Segunda linea.");
}

O podríamos escribir un nuevo método, llamado ​tresLineas​, que imprima tres nuevas líneas:

public static void tresLineas () {


nuevaLinea (); nuevaLinea (); nuevaLinea ();
}
public static void main (String[] args) {
System.out.println ("Primera linea.");
tresLineas ();
System.out.println ("Segunda linea.");
}

Deberías notar algunas cosas sobre este programa:


● Se puede llamar al mismo procedimiento repetidamente. De hecho, es muy útil hacer eso.

● Se puede hacer que un método invoque a otro método. En este caso, ​main llama a
tresLineas​ y ​tresLineas​ llama a ​nuevaLinea​. Otra vez, esto es común y muy útil.

9 ::
TSTI | UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
● En ​tresLineas escribimos tres sentencias en la misma línea de código, lo cual es válido
sintácticamente (recordar que los espacios y las nuevas líneas usualmente no cambian el
significado de un programa).
● Por otro lado, es usualmente una mejor idea poner cada sentencia en una línea distinta, para
hacer tu programa más fácil de leer. A veces rompemos esa regla en este libro para ahorrar
espacio.

Hasta ahora, puede no estar claro por qué vale la pena crear todos estos nuevos métodos. En
realidad, hay un montón de razones, pero este ejemplo demuestra solamente dos:

1. Crear un nuevo método brinda una oportunidad de dar un nombre a un grupo de sentencias.
Los métodos pueden simplificar un programa al esconder un cómputo complejo detrás de un
comando simple, y usando una frase en castellano en lugar de código complicado. ¿Qué es
más claro, ​nuevaLinea​ o ​System.out.println ("")​?

2. Crear un nuevo método puede hacer un programa más corto al eliminar código repetitivo.
Por ejemplo, ¿cómo harías para imprimir por pantalla nueve líneas nuevas consecutivas?
Podrías simplemente llamar ​tresLineas​ tres veces.

Clases y métodos
Reuniendo todos los fragmentos de código de la sección anterior, la definición completa de la clase
se ve así:

class NuevaLinea {
public static void nuevaLinea () {
System.out.println ("");
}
public static void tresLineas () {
nuevaLinea (); nuevaLinea (); nuevaLinea ();
}
public static void main (String[] args) {
System.out.println ("Primera linea.");
tresLineas ();
System.out.println ("Segunda linea.");
}
}

10 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
La primera línea indica que esta es la definición de una nueva clase llamada ​NuevaLinea​. Una clase
es una colección de métodos relacionados. En este caso, la clase llamada ​NuevaLinea contiene tres
métodos, llamados ​nuevaLinea​, ​tresLineas​, y ​main​.

La otra clase que hemos visto es la clase ​Math​. Ella contiene métodos llamados ​sqrt​, ​sin​, y muchos
otros. Cuando llamamos una función matemática, tenemos que especificar el nombre de la clase
(​Math​) y el nombre de la función. Es por eso que la sintaxis es ligeramente diferente entre los
métodos preincorporados y los métodos que escribimos nosotros:

Math.pow (2.0, 10.0);


nuevaLinea ();

La primera sentencia llama al método pow de la clase ​Math ​class (que eleva el primer argumento a
la potencia del segundo argumento)2. La segunda sentencia llama el método ​nuevaLinea​, que Java
asume (correctamente) está en la clase ​NuevaLinea​, que es la que estamos escribiendo. Si tratás de
llamar un método de una clase errónea, el compilador va a generar un error.
Por ejemplo, si tipearas: ​pow (2.0, 10.0)​;

El compilador va a decir algo como “No puedo encontrar un método llamado ​pow en la clase
NuevaLinea​.” Si has visto este mensaje, podrías haberte preguntado por qué estaba buscando ​pow
en tu definición de clase. Ahora ya lo sabés.

Programas con múltiples métodos


Cuando uno mira una definición de clase que contiene varios métodos, es tentador leerla de arriba
hacia abajo, pero eso es probable que resulte confuso, ya que ese no es el orden de ejecución del
programa.

La ejecución siempre comienza en la primera sentencia de main, independientemente de dónde esté


en el programa (en este caso lo puse deliberadamente al final). Las sentencias son ejecutadas una a
la vez, en orden, hasta alcanzar una llamada de un método. Las llamada de métodos son como una
desviación en el flujo de ejecución. En vez de ir a la siguiente sentencia, se va a la primera línea del
método llamado, ejecutando todas las sentencias ahí, y después se vuelve y retoma donde se había
dejado.
Esto suena bastante simple, excepto que hay que recordar que un método puede llamar a otro. De
esta manera, mientras estamos en la mitad de ​main​, podríamos tener que salir y ejecutar sentencias
en ​tresLineas​.

2
pow viene de power, que significa potencia.

11 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Pero mientras estamos ejecutando ​tresLineas​, somos interrumpidos tres veces y vamos a ejecutar
nuevaLinea​.

Por su parte, ​nuevaLinea llama al método pre incorporado ​println​, que causa a su vez otra
desviación. Afortunadamente, Java es un experto en llevar la cuenta de dónde está, por lo que
cuando ​println termine, retoma por donde había dejado en ​nuevaLinea​, luego retrocede hasta
tresLineas​, y por último vuelve a main de manera que el programa pueda terminar.

En realidad, técnicamente, el programa no termina al final de ​main​. En cambio, la ejecución retoma


donde había dejado en el programa que invocó a main, el cual es el intérprete de Java. El intérprete
de Java se ocupa de cosas como la eliminación de ventanas y hacer una limpieza general, y luego el
programa termina.

¿Cuál es la moraleja de esta sórdida historia? Cuando leas un programa, no lo leas desde arriba hacia
abajo. En vez de eso, seguí el flujo de ejecución.

Parámetros y argumentos
Algunos de los métodos pre incorporados que hemos usado tienen parámetros, que son valores que
se le proveen para que puedan hacer su trabajo. Por ejemplo, si queremos encontrar el seno de un
número, tenemos que indicar qué número es. Por ello, sin toma un valor ​double como parámetro.
Para imprimir una cadena, hay que proveer la cadena, y es por eso que ​println toma un ​String
como parámetro.

Algunos métodos toman más de un parámetro, como ​pow​, el cual toma dos ​doubles​, la base y el
exponente.

Notar que en cada uno de esos casos tenemos que especificar no sólo cuántos parámetros hay, sino
también de qué tipo son. Por eso no debería sorprender que cuando escribimos una definición de
clase, la lista de parámetros indica el tipo de cada parámetro. Por ejemplo:

public static void imprimirDosVeces (String rigoberto) {


System.out.println (rigoberto);
System.out.println (rigoberto);
}

Este método toma un solo parámetro, llamado rigoberto, que tiene tipo ​String​. Cualquiera sea ese
parámetro (y en este punto no tenemos idea de cuál es), es impreso dos veces. Yo elegí el nombre

12 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
rigoberto para sugerir que el nombre que das como parámetro depende de vos, pero en general
querrías elegir algo más ilustrativo que ​rigoberto​.

Para llamar este método, tenemos que proveer un ​String​. Por ejemplo, podríamos tener un
método ​main​ como este:

​ public static void main (String[] args) {


imprimirDosVeces ("No me hagas decir esto dos veces!");
}

La cadena que proporcionaste se denomina argumento, y decimos que el argumento es pasado al


método. En este caso, estamos creando una cadena que contiene el texto ​“No me hagas decir
esto dos veces!” y pasando esa cadena como un argumento a ​imprimirDosVeces donde,
contrario a sus deseos, será impreso dos veces.

Alternativamente, si tuviéramos una variable de tipo ​String podríamos usarla como un argumento
en vez de lo anterior:

​public static void main (String[] args) {


String argumento = "Nunca digas nunca.";
imprimirDosVeces (argumento);
}

Notar algo muy importante aquí: el nombre de la variable que pasamos como argumento
(argumento) no tiene nada que ver con el nombre del parámetro (​rigoberto​). Permitime decirlo
nuevamente:
El nombre de la variable que pasamos como argumento no tiene nada que ver con el nombre del
parámetro.

Pueden ser el mismo o pueden ser diferentes, pero es importante darse cuenta de que no son la
misma cosa, excepto que sucede que tienen el mismo valor (en este caso la cadena "Nunca digas
nunca."​).

El valor que proveas como argumento debe tener el mismo tipo que el parámetro del método que
invocás. Esta regla es muy importante, pero a menudo se complica en Java por dos razones:

13 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
● Hay algunos métodos que pueden aceptar argumentos con varios tipos diferentes. Por
ejemplo, es posible mandar ​cualquier ​tipo a ​print y ​println​, y hará lo correcto sin importar
qué. Este tipo de cosas es una excepción, de todas maneras.

● Si violás esta regla, el compilador suele generar un mensaje de error confuso. En vez de decir
algo como “Estás pasando un argumento de tipo erróneo a este método,” probablemente
diga algo del estilo de que no pudo encontrar un método con ese nombre que acepte un
argumento de ese tipo. Una vez que hayas visto este mensaje de error un par de veces, sin
embargo, vas a darte cuenta de cómo interpretarlo.

Diagramas de la pila de ejecución


Los parámetros y otras variables sólo existen dentro de sus propios métodos. En los confines del
main​, no existe tal cosa como ​rigoberto​. Si tratás de usarlo, el compilador se quejará. De forma
similar, dentro de ​imprimirDosVeces​ no existe tal cosa como argumento.
Una forma de llevar la cuenta de dónde cada variable está definida es con un ​diagrama de la pila de
ejecución​. El diagrama de la pila para el ejemplo anterior se ve así:

Para cada método hay un recuadro gris llamado frame que contiene los parámetros de los métodos
y las variables locales. El nombre del método aparece afuera del frame3. Como de costumbre, el
valor de cada variable es dibujado dentro de un recuadro con el nombre de la variable al lado de él.

Métodos con múltiples parámetros


La sintaxis para declarar y llamar métodos con múltiples parámetros es una fuente común de
errores. Primero, recordemos que hay que declarar el tipo de cada parámetro. Por ejemplo

​ public static void imprimirTiempo(int hora, int minuto) {


System.out.print (hora);
System.out.print (":");
System.out.println (minuto);
}

3
​frame significa marco.

14 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Puede parecer tentador escribir int ​hora​, ​minuto​, pero ese formato sólo es válido para declaraciones
de variables, no para parámetros.

Otra fuente común de confusión es que no hay que declarar los tipos de los argumentos al llamar un
método. Lo siguiente es erróneo!

int hora = 11;


int minuto = 59;
imprimirTiempo (int hora, int minuto); // ERROR!

En este caso, Java ya sabe el tipo de hora y minuto porque ha visto sus declaraciones. Es innecesario
e inválido incluir el tipo cuando se pasa como argumento. La sintaxis correcta es ​imprimirTiempo
(hora, minuto).

Ejercicio propuesto: ​Dibujar un diagrama de la pila que muestre el estado del programa cuando
main​ invoque a ​imprimirTiempo​ con los argumentos ​11​ y ​59​.

Métodos con resultados


Quizás hayas notado a esta altura que algunos de los métodos que estamos usando, tales como los
métodos ​Math​, producen resultados. Otros métodos, como ​println y ​nuevaLina​, realizan alguna
acción pero no devuelven ningún valor. Esto plantea algunas preguntas: ¿Qué pasa si llamamos a un
método y no queremos hacer nada con el resultado (por ej. no vamos a asignarlo a ninguna variable
ni usarlo como parte de una expresión más grande)? ¿Qué pasa si usamos un método ​print como
parte de una expresión, tal como ​System.out.println ("buu!") + 7​? ¿Podemos escribir métodos
que produzcan resultados, o estamos atascados con cosas como ​nuevaLinea​ e ​imprimirDosVeces​?

La respuesta a la tercera pregunta es “sí”, es posible escribir métodos que devuelvan valores”, y
vamos a hacerlo en un par de capítulos. Te dejo a vos que respondas las otras dos preguntas
intentando ver qué pasa. De hecho, siempre que tengas una pregunta acerca de qué es válido o
inválido en Java, una buena forma de averiguarlo es preguntarle al compilador.

Promoción y conversión de argumentos


Otra característica importante de las llamadas a los métodos es la promoción de argumentos:
convertir el valor de un argumento al tipo que el método espera recibir en su correspondiente
parámetro. Por ejemplo, una aplicación puede llamar al método ​sqrt de ​Math con un argumento
entero, aun cuando el método espera recibir un argumento double (pero no viceversa, como pronto

15 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
veremos). La instrucción ​System.out.println( Math.sqrt( 4 ) ); evalúa ​Math.sqrt( 4 )
correctamente e imprime el valor ​2.0​. La lista de parámetros de la declaración del método hace que
Java convierta el valor ​int 4 en el valor ​double ​4.0 antes de pasar ese valor a ​sqrt​. Tratar de
realizar
estas conversiones puede ocasionar errores de compilación, si no se satisfacen las reglas de
promoción de Java.

Las reglas de promoción especifican qué conversiones son permitidas; esto es, qué conversiones
pueden realizarse sin perder datos. En el ejemplo anterior de ​sqrt​, un ​int se convierte en ​double
sin modificar su valor. No obstante, la conversión de un ​double ​a un ​int trunca la parte fraccionaria
del valor ​double​; por consecuencia, se pierde parte del valor. La conversión de tipos de enteros
largos a tipos de enteros pequeños (por ejemplo, de ​long a ​int​) puede también producir valores
modificados.

Las reglas de promoción se aplican a las expresiones que contienen valores de dos o más tipos
simples, y a los valores de tipos simples que se pasan como argumentos para los métodos. Cada
valor se promueve al tipo “más alto” en la expresión. (En realidad, la expresión utiliza una copia
temporal de cada valor; los tipos de los valores originales permanecen sin cambios). En la siguiente
tabla se muestran los tipos primitivos y los tipos a los cuales se puede promover cada uno de ellos.
Observe que las promociones válidas para un tipo dado siempre se realizan a un tipo más alto en la
tabla. Por ejemplo, un int puede promoverse a los tipos más altos long, float y double.

Al convertir valores a tipos inferiores, se producirán distintos valores si el tipo inferior no puede
representar el valor del tipo superior (por ejemplo, el valor ​int 2000000 ​no puede representarse
como un ​short​, y cualquier número de punto fl otante con dígitos después de su punto decimal no
pueden representarse en un tipo entero como ​long​, ​int​ o ​short​).

Promociones permitidas para los tipos primitivos.

16 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Por lo tanto, en casos en los que la información puede perderse debido a la conversión, el
compilador de Java requiere que utilicemos un operador de conversión para forzar explícitamente la
conversión; en caso contrario, ocurre un error de compilación. Eso nos permite “tomar el control”
del compilador. En esencia decimos, “Sé que esta conversión podría ocasionar pérdida de
información, pero para mis fines aquí, eso está bien”. Supongamos que el método ​cuadrado calcula
el cuadrado de un entero y por ende requiere un argumento ​int​. Para llamar a cuadrado con un
argumento ​double llamado ​valorDouble​, tendríamos que escribir la llamada al método de la
siguiente forma:

cuadrado( (int) valorDouble )

La llamada a este método convierte explícitamente el valor de ​valorDouble a un entero, para usarlo
en el método cuadrado. Por ende, si el valor de valorDouble es 4.5​, el método recibe el valor ​4 ​y
devuelve ​16​, no​ 20.25.

Alcance de las declaraciones


Ya hemos visto declaraciones de varias entidades de Java como las clases, los métodos, las variables
y los parámetros. Las declaraciones introducen nombres que pueden utilizarse para hacer referencia
a dichas entidades de Java. El alcance de una declaración es la porción del programa que puede
hacer referencia a la entidad declarada por su nombre. Se dice que dicha entidad está “dentro del
alcance” para esa porción del programa. En esta sección introduciremos varias cuestiones
importantes relacionadas con el alcance.

Las reglas básicas de alcance son las siguientes:


1. El alcance de la declaración de un parámetro es el cuerpo del método en el que aparece la
declaración.

2. El alcance de la declaración de una variable local es a partir del punto en el cual aparece la
declaración, hasta el final de ese bloque.

3. El alcance de la declaración de una variable local que aparece en la sección de inicialización del
encabezado de una instrucción for es el cuerpo de la instrucción for y las demás expresiones en el
encabezado.

4. El alcance de un método o campo de una clase es todo el cuerpo de la clase. Esto permite a los
métodos no static de la clase utilizar cualquiera de los campos y otros métodos de la clase.

17 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar
Cualquier bloque puede contener declaraciones de variables. Si una variable local o parámetro en un
método tiene el mismo nombre que un campo, el campo se “oculta” hasta que el bloque termina su
ejecución; a esto se le llama ocultación de variables (shadowing).

Actividad Propuesta:​ ​resolver los problemas de la guía “Modularización”.

Resumen de la Unidad 4

La mayoría de los programas de cómputo que resuelven los problemas reales son mucho más
extensos que los programas que se presentan en las primeras unidades. La experiencia ha
demostrado que la mejor manera de desarrollar y mantener un programa extenso es construirlo a
partir de pequeñas piezas sencillas, o módulos. A esta técnica se le llama ​divide y vencerás​.
Hasta aquí, hemos avanzado en las técnicas de diseño de algoritmos. Llega entonces el momento
de comenzar a diseñar estructuras de datos más complejas que permitan almacenar los datos y
accederlos de manera eficiente, en la unidad 5 trabajaremos en ello.

Glosario
punto flotante​: Tipo de variable (o valor) que puede contener tanto fracciones como enteros. En
Java este tipo se llama ​double​.
clase​: Nombre para una colección de métodos. Hasta ahora, hemos usado las clases ​Math y ​System y
hemos escrito clases llamadas Hola y ​NuevaLinea​.
método​: Nombre para una secuencia de sentencias que realiza alguna función útil. Los métodos
pueden o no tomar parámetros, y pueden o no producir un resultado.
parámetro​: Pieza de información que se provee al llamar un método. Los parámetros son como las
variables en el sentido de que contienen valores y son de algún tipo.
argumento​: Valor que se provee cuando se llama a un método. Este valor debe tener el mismo tipo
que el parámetro correspondiente. En castellano, parámetro y argumento tienden a utilizarse
indistintamente.
llamar/invocar​: Causar que un método sea ejecutado.

18 ::| UNIVERSIDAD TECNOLÓGICA NACIONAL . FACULTAD REGIONAL SANTA FE


TSTI
TE +54 (342) 460 1579 / 2390 - FAX 469 0348 / tsti.frsf.utn.edu.ar

Potrebbero piacerti anche