SI EL MÉTODO ES UNA CAJA NEGRA, los parámetros  proporcionan el medio para traspasar información desde fuera al mundo interior de la caja. Los parámetros forman parte de la interface del método. Ellos permiten personalizar el comportamiento del método para adaptarlo a situaciones particulares.

Como analogía, considere un termostato — una caja negra cuya tarea consiste en mantener su casa a una cierta temperatura. El termostato tiene un parámetro , que es el selector que emplea para indicar la temperatura deseada. El termostato siempre realiza la misma tarea: mantener constante la temperatura. Sin embargo, la tarea exacta que realiza–esto es, la temperatura que mantiene– se personaliza indicándola en el selector.

Veamos un ejemplo, retrocedamos al problema «3N+1» que se presento anteriormente (Recuerde que 3N+1 es la secuencia calculada según la siguiente regla, «Si N es impar, se multiplica por 3 y se le suma 1; si N es par, se divide por 2; continuar hasta que N sea igual a 1.»

Por ejemplo empezando en 3, se obtiene la secuencia: 3,10,5,16,8,4,2,1). Supongamos que quiere escribir un método para imprimir esta secuencia. El método siempre hará el mismo trabajo: Imprimir la secuencia 3N+1. Pero la secuencia exacta que se imprima, dependerá del valor de N. Entonces el valor inicial de N puede ser un parámetro del método y podría escribirse así:

         static void Print3NSequence(int startingValue) {

            // imprimir en consola la secuencia 3N+1 usando
            // startingValue como valor inicial de N

            int N = startingValue;  //para el elemento de la secuencia
            int count = 1;   // cuenta el numero de elementos

            console.putln("La secuencia 3N+1 empieza en " + N);
            console.putln();
            console.putln(N);  // imprimir el primer termino

            while (N > 1) {
                if (N % 2 == 1)     // N es par?
                   N = 3 * N + 1;
                else
                   N = N / 2;
                count++;   // contar el elemento
                console.putln(N);  // imprimir elemento
            }

            console.putln();
            console.putln("Hay " + count + " elementos en la secuencia.");

         }  // fin de  Print3NSequence()

Este método puede llamarse utilizando una instrucción como

«Print3NSequence(17);«

,que imprimirá la secuencia 3N+1 empezando en 17. Si k es una variable de tipo int, la instrucción «Print3NSequence(k);» imprimirá la secuencia 3N+1 empezando en K, que es como podíamos esperar, el valor de k cuando se ejecuta la instrucción.

Puedo usar el método en un programa que permita al usuario el imprimir la secuencia empezando en diferentes valores:

         public static void main(String[] args) {
            console = new Console();
            console.putln("Este programa imprime la secuencia 3N+1");
            console.putln("empezando en el valor que le indique.");
            console.putln();
            do {
               console.putln("Indique valor inicial;")
               console.put("Para finalizar el programa entre 0: ");
               int K = console.getInt();  // lee valor inicial
               if (K > 0)   // imprime secuencia se  K es > 0
                  Print3NSequence(K);
            } while (K > 0);   // continua solo si K > 0
         } // end main()


En realidad existen dos tipos muy diferentes de parámetros: Los parámetros que se emplean en la definición del método, y los parámetros que se pasan cuando se llama al método. En la definición del método los parámetros se llaman parámetros formales o falsos parámetros. Los parámetros que se pasan al método cuando se llama se denominan parámetros reales.

Los parámetros formales pueden ser identificadores, oséa nombres.

Un parámetro formal es mucho mas semejante a una variable y, como las variables, se le tiene que indicar el tipo como int, boolean, o String Un parámetro real es un valor, y como tal, puede estar representado por cualquier expresión, mientras que la expresión proporcione un valor del tipo adecuado.

Cuando llama a un método, debe proporcionar un parámetro real por cada uno de los parámetros formales que haya en la definición del método.

El ordenador evalúa cada parámetro real e inicializa con ese valor el correspondiente parámetro formal. Considere por ejemplo el método:

         static void doTask(int N, double x, boolean test) {
             // aquí, las instrucciones
         }

Este método puede ser llamada con la siguiente instrucción

doTask(17,Math.sqrt(z+1),z>=10);

Cuando el ordenador ejecuta esta instrucción, básicamente tiene el mismo efecto que el siguiente bloque:

 

      {
        int N = 17; // declara un int llamado N con valor inicial 17
        double x = Math.sqrt(z+1);  // calcula Math.sqrt(z+1), y 
              // lo emplea para inicializar x de tipo double
        boolean test = (z >= 10); // evalúa "z >= 10"
              // y usa el resultado true/false para inicializar
              // una nueva variable llamada test
        // aquí las instrucciones
      }

Existe alguna pequeña diferencia técnica entre esto y «doTask(17,Math.sqrt(z+1),z>=10);» –aparte de la cantidad  a escribir– debido a temas como los ámbitos (scope) de las variables, y lo que puede pasar cuando varias variables o parámetros tienen el mismo nombre.)


Como puede ver, para poder llamar correctamente a un método, necesita conocer su nombre, necesita conocer cuantos parámetros tiene y necesita conocer el tipo de cada parámetro.

Esta información se llama firma (signature) del método. La firma del método doTask se puede escribir como: doTask(int,double,boolean). Observe que en la firma no se incluyen los nombres de lo parámetros; de hecho, si quiere usar el método, no necesita conocer los nombres para nada, ya que los nombres no son parte de la interface. Los nombres solo los ha empleado la persona que ha escrito el método.

Java es algo especial en el hecho de que permita que dos subrutinas dentro de una misma clase puedan tener el mismo nombre, mientras que sus firmas sean diferentes.

El lenguaje C++ el el que se basa Java también tiene esa característica.

Decimos que el nombre del método puede ser sobrecargado (overloaded) porque tiene diferentes propósitos. El ordenador consigue diferenciar las subrutinas. Puede decirle cual de ellas quiere llamar por el numero de parámetros y los tipos que proporciona en la instrucción de llamada.

En la clase Console ya ha visto como se empleaban las sobrecargadas.En esa clase, por ejemplo, se incluyen muchos métodos diferentes llamados putln. Esos métodos tienen todos firmas distintas, como:

      putln(int)       putln(int,int)      putln(double)
      putln(String)    putln(String,int)   putln(char)
      putln(boolean)   putln(boolean,int)  putln()

Naturalmente que cada una de esos métodos están relacionados semánticamente, esa es la razón para emplear el mismo nombre para todas ellas. Pero en lo que al ordenador concierne imprimir un int es muy diferente a imprimir una String que a su vez es muy diferente a imprimir un boolean, y así sucesivamente; y por eso cada una de estas operaciones requieren un método diferente.

A propósito, observe que dentro de la firma no esta incluido el tipo de retorno del método. Es ilegal el que haya en una misma clase dos métodos que tengan la misma firma pero distinto tipo de retorno. Por ejemplo es un error de sintaxis que en una misma clase haya dos métodos definidos como:

        int    get() { ... }
        double get() { ... }

Por eso, no debe sorprenderse que el la clase Console , los métodos que leen diferentes tipos, tengan nombres diferentes como getInt()y getDouble().


Finalizaré esta sección sobre los parámetros, señalando que de momento tenemos tres tipos diferentes de variables que pueden emplearse dentro de los métodos: Las variables locales que se definen dentro de ellos, los nombres de los parámetros formales, y las variables que se definen fuera del método pero que son miembros de la misma clase.

Una variable local, no tiene conexión con el mundo exterior; únicamente forma parte del área de trabajo interna del método.

Los parámetros se usan  cuando se llama al método, para «introducir» valores, pero una vez se inicia la ejecución del método, los parámetros se parecen mucho a las variables locales.

Los cambios que se realizan dentro del método a los parámetros formales, no tienen efecto en el resto del programa ( por lo menos si los parámetros son de uno de los tipos primitivos– las cosas son bastante mas complicadas cuando se trata de objetos, como veremos mas adelante).

Una tema diferente es cuando el método emplea variables definidas fuera . Estas variables existen de forma independiente del método, y son accesibles desde otras partes del programa de la misma forma que desde el método.

Estas variables se conocen como globales, por oposición a las variables locales del método.

El ámbito de una variable global es toda la clase en la que esta definida. Los cambios realizados en una variable global, se extienden mas allá del método que los realiza. Esto no es necesariamente malo, pero debe considerar la variable global como una parte de la interface del método.

Este emplea las variables globales para comunicarse con el resto del programa. Es una especie de falsa comunicación realizada por la puerta trasera, que es mucho menos visible que la hecha a través de los parámetros y se corre el riesgo de violar la regla de la interface de una caja negra que habla de que debe ser directa y fácil de entender.

No quiero decirle que deba estar en contra de emplear las variables globales dentro de los procedimientos. Hay al menos una buena razón para hacerlo: Si piensa que la clase es en principio, un tipo de caja negra, puede ser razonable hacer que las subrutinas que están dentro de esa caja, tengan alguna comunicación unas con otras, si eso hace que la clase se vea mucho mas sencilla desde el exterior.

Sin embargo, debe definitivamente el evitar emplear las variables globales cuando los parámetros puedan ser mas apropiados. (Aunque ya se que es un tema bastante difícil de juzgar).

Un comentario sobre “Java para programadores. Los Parametros”

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.