TutorJava Nivel Básico

Cuando se escribe un m�todo, se declara el n�mero y tipo de los argumentos requeridos por ese m�todo. Esto se hace en la firma del m�todo. Por ejemplo, el siguiente m�todo calcula el pago mensual de una hipoteca bas�ndose en la cantidad prestada, el inter�s, la duraci�n de la hipoteca (n�mero de meses) y el valor futuro de la hipoteca (presumiblemente el valor futuro sea cero, porque al final de la hipoteca, ya la habr�s pagado).

double hipoteca(double cantidad, double interes, double valorFinal, int numPeriodos) {
    double I, parcial1, denominador, respuesta;

    I = interes / 100.0;
    parcial1 = Math.pow((1 + I), (0.0 - numPeriodos));
    denominador = (1 - parcial1) / I;
    respuestar = ((-1 * cantidad) / denominador) - ((valorFinal * parcial1) / denominador);
    return respuesta;
}

Este m�todo toma cuatro argumentos: la cantidad prestada, el inter�s, el valor futuro y el n�mero de meses. Los tres primeros son n�meros de coma flotante de doble precisi�n y el cuarto es un entero.

Al igual que este m�todo, el conjunto de argumentos de cualquier m�todo es una lista de declaraciones de varibales delimitadas por comas donde cada declaraci�n de variable es un par tipo/nombre.

tipo nombre

Como has podido ver en el ejemplo anterior, s�lo tienes que utilizar el nombre del argumento para referirte al valor del argumento.

.�Tipos de Argumentos

En Java, se puede pasar como argumento a un m�todo cualquier tipo de dato v�lido en Java. Esto incluye tipos primitivos, como enteros, dobles, etc.. y tipos de referencia como arrays, objetos, etc...

Aqu� tienes un ejemplo de un constructor que acepta un array como argumento. En este ejemplo el constructor inicializa un objeto Polygon a partir de una lista de puntos (Point es una clase del paquete java.awt que representa una coordenada xy).

Polygon polygonFrom(Point[] listadePuntos) {
    . . .
}

Al contrario que en otros lenguajes, no se puede pasar un m�todo a un m�todo Java. Pero si se podr�a pasar un objeto a un m�todo y luego llamar a los m�todos del objeto.

.�Nombres de Argumentos

Cuando se declara un argumento para un m�todo Java, se proporciona el nombre para ese argumento. Este nombre es utilizado dento del cuerpo del m�todo para referirse al valor del argumento.

Un argumento de un m�todo puede tener el mismo nombre que una variable de la clase. En este caso, se dice que el argumento oculta a la variable miembro. Normalmente los argumentos que ocultan una variable miembro se utilizan en los constructores para inicializar una clase. Por ejemplo, observa la clase Circle y su constructor.

class Circle {
    int x, y, radius;
    public Circle(int x, int y, int radius) {
        . . .
    }
}

La clase Circle tiene tres variables miembro x, y y radius. Adem�s, el constructor de la clase Circle acepta tres argumentos cada uno de los cuales comparte el nombre con la variable miembro para la que el argumento proporciona un valor inicial.

Los nombres de argumentos ocultan los nombres de las variables miembro. Por eso utilizar x, y o radius dentro del cuerpo de la funci�n, se refiere a los argumentos, no a las variables miembro. Para acceder a las variables miembro, se las debe referenciar a trav�s de this--el objeto actual.

class Circle {
    int x, y, radius;
    public Circle(int x, int y, int radius) {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }
}

Los nombres de los argumentos de un m�todo no pueden ser el mismo que el de otros argumentos del mismo m�todo, el nombre de cualquier variable local del m�todo o el nombre de cualquier par�metro a una clausula catch() dentro del mismo m�todo.

.�Paso por Valor

En los m�todos Java, los argumentos son pasados por valor. Cuando se le llama, el m�todo recibe el valor de la variable pasada. Cuando el argumento es de un tipo primitivo, pasar por valor significa que el m�todo no puede cambiar el valor. Cuando el argumento es del tipo de referencia, pasar por valor significa que el m�todo no puede cambiar el objeto referenciado, pero si puede invocar a los m�todos del objeto y puede modificar las variables accesibles dentro del objeto.

Consideremos esta serie de sentencias Java que intentan recuperar el color actual de un objeto Pen en una aplicaci�n gr�fica.

. . .
int r = -1, g = -1, b = -1;
pen.getRGBColor(r, g, b);
System.out.println("red = " + r + ", green = " + g + ", blue = " + b);
. . .

En el momento que se llama al m�todo getRGBColor(), las variables r, g, y b tienen un valor de -1. El llamador espera que el m�todo getRGBColor() le devuelva los valores de rojo, verde y azul para el color actual en las variables r, g, y b.

Sin embargo, el sistema Java pasa los valores de las variables(-1) al m�todo getRGBColor(); no una referencia a las variables r, g, y b.

Con esto se podr�a visualizar la llamada a getRGBColor() de esta forma.

getRGBColor(-1, -1, -1)

Cuando el control pasa dentro del m�todo getRGBColor(), los argumentos entran dentro del �mbito (se les asigna espacio) y son inicializados a los valores pasados al m�todo.

class Pen {
    int valorRojo, valorVerde, valorAzul;
    void getRGBColor(int rojo, int verde, int azul) {
        // rojo, verde y azul han sido creados y sus valores son  -1
        . . .
    }
}

Con esto getRGBColor() obtiene acceso a los valores de r, g, y b del llamador a tav�s de sus argumentos rojo, verde, y azul, respectivamente.

El m�todo obtiene su propia copia de los valores para utilizarlos dentro del �mbito del m�todo. Cualquier cambio realizado en estas copias locales no sera reflejado en las variables originales del llamador.

Ahora veremos la implementaci�n de getRGBColor() dentro de la clase Pen que implicaba la firma de m�todo anterior.

class Pen {
    int valorRojo, valorVerde, valorAzul;
    . . .
        // Este m�todo no trabaja como se espera
    void getRGBColor(int rojo, int verde, int azul) {
        rojo = valorRojo;
        verde=valorVerde;
        azul=valorAzul;
    }
}

Este m�todo no trabajar� como se espera. Cuando el control llega a la sentencia println() en el siguiente fragmento de c�digo, los argumentos rojo, verde y azul de getRGBColor() ya no existen. Por lo tanto las asignaciones realizadas dentro del m�todo no tendr�n efecto; r, g, y b seguiran siendo igual a -1.

. . .
int r = -1, g = -1, b = -1;
pen.getRGBColor(r, g, b);
System.out.println("rojo = " + r + ", verde = " + g + ", azul = " + b);
. . .

El paso de las varibales por valor le ofrece alguna seguridad a los programadores: los m�todos no puede modificar de forma no intencionada una variable que est� fuera de su �mbito.

Sin embargo, alguna vez se querr� que un m�todo modifique alguno de sus argumentos. El metodo getRGBColor() es un caso apropiado. El llamador quiere que el m�todo devuelva tres valores a trav�s de sus argumentos. Sin embargo, el m�todo no puede modificar sus argumentos, y, adem�s, un m�todo s�lo puede devolver un valor a trav�s de su valor de retorno. Entonces, �c�mo puede un m�todo devolver m�s de un valor, o tener alg�n efecto (modificar alg�n valor) fuera de su �mbito?

Para que un m�todo modifique un argumento, debe ser un tipo de referencia como un objeto o un array. Los objetos y arrays tambi�n son pasados por valor, pero el valor de un objeto es una referencia. Entonces el efecto es que los argumentos de tipos de referencia son pasados por referencia. De aqu� el nombre. Una referencia a un objeto es la direcci�n del objeto en la memoria. Ahora, el argumento en el m�todo se refiere a la misma posici�n de memoria que el llamador.

Reescribamos el m�todo getRGBColor() para que haga lo que queremos. Primero introduzcamos un nuevo objeto RGBColor, que puede contener los valores de rojo, verde y azul de un color en formato RGB.

class RGBColor {
    public int rojo, verde, azul;;
}

Ahora podemos reescribir getRGBColor() para que acepte un objeto RGBColor como argumento. El m�todo getRGBColor() devuelve el color actual de l�piz, en los valores de las variables miembro rojo, verde y azul de su argumento RGBColor.

class Pen {
    int valorRojo, valorVerde, valorAzul;
    void getRGBColor(RGBColor unColor) {
        unColor.rojo = valorRojo;
        unColor.verde = valorVerde;
        unColor.azul = valorAzul;
    }
}

Y finalmente, reescribimos la secuencia de llamada.

. . .
RGBColor penColor = new RGBColor();
pen.getRGBColor(penColor);
System.out.println("ojo = " + penColor.rojo + ", verde = " + penColor.verde + ",
                   azul = " + penColor.azul);
. . .

Las modificaciones realizadas al objeto RGBColor dentro del m�todo getRGBColor() afectan al objeto creado en la secuencia de llamada porque los nombres penColor (en la secuencia de llamada) y unColor (en el m�todo getRGBColor()) se refieren al mismo objeto.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP