Métodos

Correspondencia en Python —>

Java es un lenguaje de programación especialmente diseñado para trabajar con clases y objetos.
Un método es un bloque de código que se va a encargar de efectuar una determinada tarea con un objeto cuando sea invocado por dicho objeto.

Un tipo importante de método, es el que está declarado como static. Los métodos static son lo más parecido a las funciones de otros lenguajes como Python. Se pueden llamar desde cualquier lugar del código solo hace falta mencionar la clase y el nombre del método, pero no están ligados a ningún objeto de clase, es decir, no precisan de instanciar un objeto para ser utilizadas.
Estos métodos static, pueden estar dentro de cualquier clase y también dentro del bloque principal main.

Una parte importante del método es que puede ser llamado tantas veces como se precise. Es un código reutilizable.
Vemos el método saludo( )

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Prueba3 {
    public static void main(String[] args) {
        List<String> invitados = new ArrayList<>(Arrays.asList("Pedro", "Juan", "Javier"));
        for (String invitado : invitados) {
            System.out.println("Saludamos a " + invitado);
            saludo();
        }
    }

    public static void saludo(){
        System.out.println("Hola. Bienvenido al grupo.");
    }
}
Resultado:

Saludamos a Pedro
Hola. Bienvenido al grupo.
Saludamos a Juan
Hola. Bienvenido al grupo.
Saludamos a Javier
Hola. Bienvenido al grupo.

Métodos y Parámetros.

El uso de los métodos se vuelve más interesante cuando les pasamos argumentos para que puedan trabajar con ellos. Para que esto pueda ser posible, al definir el método debemos añadir uno o más parámetros entre paréntesis. El método tomará los argumentos recibidos y los convertirá en variables locales para ser usadas dentro de su código. Los argumentos pueden ser cualquier tipo de dato, pero deben de coincidir con los parámetros que espera recibir.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Prueba3 {
    public static void main(String[] args) {
        List<String> invitados = new ArrayList<>(Arrays.asList("Pedro", "Juan", "Javier"));
        for (String invitado : invitados) {
            saludo(invitado);
        }
    }

    public static void saludo(String invitado){
        System.out.println("Hola. Bienvenido al grupo.");
        System.out.println("Saludamos a " + invitado);
    }
}
Resultado:

Hola. Bienvenido al grupo.
Saludamos a Pedro
Hola. Bienvenido al grupo.
Saludamos a Juan
Hola. Bienvenido al grupo.
Saludamos a Javier

En la definición del método podemos añadir tantos parámetros como creamos necesarios. Como regla general, al invocar al método deberemos de añadir tantos argumentos como parámetros estén incluidos en su definición, y además deben de estar informados en el mismo orden y contener el mismo tipo de datos.

public class Prueba3 {
    public static void main(String[] args) {

        float compra_1=producto("leche",10, 1.28F,4);
        float compra_2=producto("pan",20, 0.65F,4);
        float compra_3=producto("aceite",2, 8.20F,12);

        float total_compra=(compra_1+compra_2+compra_3);
        System.out.println("\nEl importe de su compra es: "+total_compra);
    }

    public static float producto(String nombre,int cantidad,float precio_unidad,float iva){
        float total_sin_iva=cantidad*precio_unidad;
        float resultado=(total_sin_iva*(1+(iva/100)));
        System.out.println("Producto: "+ nombre+". Total producto: " + resultado);
        return resultado;
    }
}
Resultado:

Producto: leche. Total producto: 13.311998
Producto: pan. Total producto: 13.5199995
Producto: aceite. Total producto: 18.368

El importe de su compra es: 45.199997

La instrucción return

En el ejemplo anterior, hemos visto que se ha añadido una instrucción “return” en el cuerpo del método. Esta instrucción no es obligada, pero nos ayuda a devolver a la parte del programa que le llama, un dato que luego puede seguir utilizándose.

Si el método no va a devolver ningún dato, el «return» simplemente servirá para indicar que el control se devuelve al punto de llamada.

Si debemos devolver algún tipo de dato, al nombrar el método debemos especificar el tipo de dato de retorno, en lugar de la palabra reservada «void» que indicaría que no se devuelve ningún valor.


Lo normal es que si el método va a devolver algún dato, ese dato quede almacenado en la variable que le llama, aunque también podemos aplicar dicho valor directamente en una expresión que forme parte del código, como haríamos con cualquier otro valor.

Un método también puede ser llamado desde otro método:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Prueba3 {
    public static void main(String[] args) {
        List<String> invitados = new ArrayList<>(Arrays.asList("Pedro", "Juan", "Javier"));
        for (String invitado : invitados) {
            nuevo_alumno(invitado);
        }
    }

    public static void nuevo_alumno(String nombre){
        System.out.println("Saludamos a " + nombre);
        saludo(nombre);
    }

    public static void saludo(String invitado){
        System.out.println("Hola "+invitado+". Bienvenido al grupo."+"\n");
    }
}
Resultado:

Saludamos a Pedro
Hola Pedro. Bienvenido al grupo.

Saludamos a Juan
Hola Juan. Bienvenido al grupo.

Saludamos a Javier
Hola Javier. Bienvenido al grupo.

La instrucción return (si existe), no debe de estar siempre al final del código del método. Puede estar incluida en cualquier otro lugar de su código. En el momento en que aparezca un “return” (puede haber varios incluidos dentro del mismo método), se devuelve automáticamente el control a la parte del programa que le llama.
Veamos un ejemplo con un método que recibe como argumento un ArrayList.

import java.util.ArrayList;
import java.util.Arrays;

public class Prueba3 {
    public static void main(String[] args) {
        ArrayList<Integer> listado = new ArrayList<>(Arrays.asList(5, 76, 14, 38, 100));
        String mensaje=divisible(listado);
        System.out.println(mensaje);
    }

    public static String divisible(ArrayList<Integer> mi_listado) {
        for (int numero : mi_listado) {
            if (numero % 7 == 0) {
                return ("El número " + numero + " es divisible entre 7.");
            }
        }
        return ("No hemos encontrado ningún número divisible entre 7.");
    }
}
Resultado:

El número 14 es divisible entre 7.

Sobrecarga de métodos.

La sobrecarga de métodos consiste en dos (o más) métodos que tienen el mismo nombre, pero distinto número de parámetros, o incluso también el mismo número de parámetros pero (al menos uno) de diferente tipo.

Veamos un ejemplo con uno de los programas anteriores, donde el método «producto» recibía antes 4 parámetros. Crearemos un nuevo método idéntico, pero que solo reciba 3 parámetros.

public class Prueba3 {
    public static void main(String[] args) {

        float compra_1=producto("leche",10, 1.28F);
        float compra_2=producto("pan",20, 0.65F);
        float compra_3=producto("aceite",2, 8.20F);

        float total_compra=(compra_1+compra_2+compra_3);
        System.out.println("\nEl importe de su compra es: "+total_compra);
    }

    public static float producto(String nombre,int cantidad,float precio_unidad,float iva){
        float total_sin_iva=cantidad*precio_unidad;
        float resultado=(total_sin_iva*(1+(iva/100)));
        System.out.println("Producto: "+ nombre+". Total producto: " + resultado);
        return resultado;
    }

    public static float producto(String nombre, int cantidad, float precio_unidad){
        float iva=7.0F;
        float total_sin_iva=cantidad*precio_unidad;
        float resultado=(total_sin_iva*(1+(iva/100)));
        System.out.println("Producto: "+ nombre+". Total producto: " + resultado);
        return resultado;
    }
}
Resultado:

Producto: leche. Total producto: 13.696
Producto: pan. Total producto: 13.910001
Producto: aceite. Total producto: 17.548

El importe de su compra es: 45.154

En el método sobrecargado con 3 parámetros, establecemos el iva como fijo para todos los productos en 7, por lo tanto no hace falta pasarle el 4º parámetro en la llamada al método, que tampoco espera recibirlo.

Métodos y variables. Variables locales y variables static

Un detalle muy importante a tener en cuenta es el valor que pueden tomar las variables dentro de un método. Una variable declarada dentro de un método, solo será reconocida dentro de dicho método.

public class Prueba3 {
    public static void main(String[] args) {
        float salario=2000F;
        float irpf=0.15F;
        float gastos=1500;
        float ahorro=salario*(1-irpf)-gastos;
        System.out.println("El ahorro antes de intereses banco es: "+ahorro);
        ahorro_banco(ahorro,500);
        System.out.println("El ahorro sumados ahorro banco es: "+ahorro);
    }

    public static void ahorro_banco( float ahorro_anterior, float intereses_banco){
        float ahorro=(ahorro_anterior)+intereses_banco*(1-irpf);
        System.out.println("Según el método, el ahorro sumados intereses del banco es: "+ahorro);
    }

}

Si intentamos compilar este código, nos dará error. El problema que nos encontramos es que el método ahorro_banco no reconoce la variable irpf porque pertenece al ámbito del método principal main.

Para solucionarlo declaramos la variable como variable de clase (no de método), y hacemos que esté disponible para cualquier método de la clase. Esto lo hacemos con el modificador static.

public class Prueba3 {
        static float irpf;

    public static void main(String[] args) {
        float salario=2000F;
        irpf=0.15F;
        float gastos=1500;
        float ahorro=salario*(1-irpf)-gastos;
        System.out.println("El ahorro antes de intereses banco es: "+ahorro);
        ahorro_banco(ahorro,500);
        System.out.println("El ahorro sumados ahorro banco es: "+ahorro);
    }

    public static void ahorro_banco( float ahorro_anterior, float intereses_banco){
        float ahorro=(ahorro_anterior)+intereses_banco*(1-irpf);
        System.out.println("Según el método, el ahorro sumados intereses del banco es: "+ahorro);
    }

}
Resultado:

El ahorro antes de intereses banco es: 200.0
Según el método, el ahorro sumados intereses del banco es: 625.0
El ahorro sumados ahorro banco es: 200.0

Vemos que el resultado tampoco es el esperado. Esto es porque tenemos dos variables llamadas igual («ahorro»), pero que son variables locales para cada uno de los métodos que la declara. La solución es la misma, declarar esta variable como variable de clase y añadirle el modificador static.

public class Prueba3 {
        static float irpf;
        static float ahorro;

    public static void main(String[] args) {
        float salario=2000F;
        irpf=0.15F;
        float gastos=1500;
        ahorro=salario*(1-irpf)-gastos;
        System.out.println("El ahorro antes de intereses banco es: "+ahorro);
        ahorro_banco(ahorro,500);
        System.out.println("El ahorro sumados ahorro banco es: "+ahorro);
    }

    public static void ahorro_banco( float ahorro_anterior, float intereses_banco){
        ahorro=(ahorro_anterior)+intereses_banco*(1-irpf);
        System.out.println("Según el método, el ahorro sumados intereses del banco es: "+ahorro);
    }

}
Resultado:

El ahorro antes de intereses banco es: 200.0
Según el método, el ahorro sumados intereses del banco es: 625.0
El ahorro sumados ahorro banco es: 625.0

Ahora sí nos concuerda todo.

Los parámetros serán variables locales dentro del método.

Cuando un método recibe un parámetro (y aunque ese parámetro tenga el mismo nombre que otra variable definida fuera del método), el parámetro pasará a ser una variable local para el método. Si se modifica dentro del método, no quedará modificada también fuera.

public class Prueba3 {

    public static void main(String[] args) {
        float dividendo=9F;
        float divisor=2;
        float resultado=division(dividendo,divisor);
        System.out.println(resultado);
        System.out.println(dividendo);
    }

    public static float division( float dividendo, float divisor){
        dividendo=dividendo+1;
        float division=dividendo/divisor;
        return division;
    }
}
Resultado:

5.0
9.0

Hemos modificado dentro del método el parámetro dividendo, sin embargo la variable dividendo ha quedado sin tocar fuera de dicho método.

ArrayList como parámetro.

Una pequeña diferencia está en si pasamos como argumento un ArrayList (o un dato tipo objeto). En este caso, si modificamos el ArrayList (o el dato) dentro del método, SI que quedará modificado en origen.

import java.util.ArrayList;
import java.util.Arrays;

public class Prueba {
    public static void main(String[] args) {
        ArrayList<Integer> mis_numeros = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
        duplicar(mis_numeros);
        System.out.println(mis_numeros);
    }

    public static void duplicar(ArrayList <Integer> mis_numeros) {
        for (int k = 0; k<mis_numeros.size(); k++){
            int antes=mis_numeros.get(k);
            mis_numeros.set(k,antes*2);
        }
    }
}
Resultado:

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Archivo de métodos.

Puede sernos de utilidad crear un archivo dentro de nuestro proyecto que contenga una serie de métodos que estén todos relacionados entre sí. Por ejemplo, podemos tener un archivo llamado Financieras que contenga la clase Financieras con una serie de métodos que se encarguen de gestionar las finanzas.

public class Financieras {

    public static double intereses(double cantidad, double tipo, double meses) {
        double interes = cantidad + (cantidad * tipo / 100 * meses);
        return (interes);
    }

    public static double descuentos(double cantidad, double descuento) {
        double midescuento = cantidad - (cantidad * descuento / 100);
        return (midescuento);
    }

    public static double nominas(double sueldo,double primas, double irpf) {
        double bruto = sueldo + primas;
        double neto = bruto - (bruto * irpf / 100);
        return (neto);
    }
}

Estos métodos los hemos definido todos como «static», simplemente porque así pueden ser utilizados desde fuera de la clase sin necesidad de instanciar un objeto de la clase «Financieras».

Para poder ser utilizados estos métodos, tan solo deben de ser mencionados anteponiendo el prefijo de la clase.

public class Prueba3 {

    public static void main(String[] args) {
        double mi_sueldo= Financieras.nominas(1200,500,12);
        System.out.println("Mi sueldo es: "+mi_sueldo+" euros.");
    }
}
Resultado:

Mi sueldo es: 1496.0 euros.

El ejemplo anterior implica que el archivo de métodos esté en el mismo directorio que el archivo donde se encuentra «main».

Pero puede ocurrir también de que tengamos una carpeta (paquete) diferente dentro de nuestro proyecto que contenga una serie de ficheros, todos ellos con métodos relacionados entre sí, y listos para usarse. Por ejemplo, supongamos que tenemos una carpeta donde uno de sus archivos sea el que contenga la clase Financieras, además de otros muchos archivos con más métodos.

En este caso, también podemos utilizarlos, pero debemos primero de importarlos:

import Utilidades.Financieras;

public class Prueba3 {

    public static void main(String[] args) {
        double mi_sueldo= Financieras.nominas(1200,500,12);
        System.out.println("Mi sueldo es: "+mi_sueldo+" euros.");
    }
}

El resultado será el mismo.

Recursividad de los métodos.

Una de las características de los métodos es la recursividad. Gracias a ella, un método puede llamarse a sí mismo. Por ejemplo, podemos hallar el factorial de un número con un método recursivo:

public class Prueba3 {
    static int numero;

    public static void main(String[] args) {
        numero = 8;
        int inicio = numero;
        System.out.println(numero);
        if (numero > 2) {
            int resultado = mifactorial(numero);
            System.out.println("Factorial de " + inicio + " es " + resultado);
        } else {
            System.out.println("El factorial de 2 es 2.");
        }
    }

        public static int mifactorial ( int n) {
            if (n > 2) {
                System.out.println(numero + "*" + (n - 1) + "=" + (numero * (n - 1)));
                numero = numero * (n - 1);
                return (mifactorial(n - 1));
            }
            else {
                return numero;
            }
        }
    }
Resultado:

8
8*7=56
56*6=336
336*5=1680
1680*4=6720
6720*3=20160
20160*2=40320
Factorial de 8 es 40320

Este método se va llamando a sí mismo hasta que n vale 3. En ese momento se multiplica el acumulado por (n-1) que es 2 y se vuelve a llamar con el valor de 2. Pero en la nueva llamada ya no se ejecuta el condicional (en realidad tocaría multiplicar el acumulado por 2-1 que sería 1) y se sale devolviendo el acumulado al flujo principal.

Otro ejemplo de recursividad. En este caso el método se va llamando a sí mismo hasta que la cadena queda vacía, momento en el cual se sale del método.

public class Prueba3 {
    static int numero;

    public static void main(String[] args) {
        String cadena="abcdefghijklmnopqrstuvwxyz";
        alfabeto(cadena);
    }

    public static void alfabeto (String cadena) {
        if (cadena.length()==0) {
            return;
        }
        else {
            System.out.println(cadena);
            cadena = cadena.substring(0, cadena.length() - 1);
            alfabeto(cadena);
        }
    }
}
Resultado:

abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwx
abcdefghijklmnopqrstuvw
abcdefghijklmnopqrstuv
abcdefghijklmnopqrstu
abcdefghijklmnopqrst
abcdefghijklmnopqrs
abcdefghijklmnopqr
abcdefghijklmnopq
abcdefghijklmnop
abcdefghijklmno
abcdefghijklmn
abcdefghijklm
abcdefghijkl
abcdefghijk
abcdefghij
abcdefghi
abcdefgh
abcdefg
abcdef
abcde
abcd
abc
ab
a
InicioComandos JavaBloques de código.
Comentar códigoSystem.out.printScanner (System.in)
Captura de erroresStringDatos Numéricos
Elementos aleatoriosDatos Fecha/horaConstantes
Bucles forBucles whileBloque if
ArraysArrayListswitch case
HashSetHashMapMétodos.
ClasesArchivosEntorno gráfico Swing
JFrame (Ventanas)Componentes básicos.