Introducción a las Funciones
Conforme aumenta la extensión y la complejidad de un programa, es habitual tener que implementar, en distintas partes, la misma funcionalidad, cosa que implica copiar una y otra vez, donde sea necesario, el mismo fragmento de código. Esto genera dos problemas:
- Duplicidad del código: Aumenta el tamaño del código y lo hace menos legible.
- Dificultad en el mantenimiento: Cualquier modificación necesaria dentro del fragmento de código repetido tendría que realizarse en todos y cada uno de los lugares donde se encuentra.
Podríamos pensar en utilizar un bucle, pero si el código se repite en lugares separados del programa, esto no es posible.
Problema del código repetido
Conceptos Básicos de Funciones
La solución para cuando necesitamos la misma funcionalidad en distintos lugares de nuestro código no es más que etiquetar con un nombre un fragmento de código y sustituir en el programa dicho fragmento, en todos los lugares donde aparezca, por el nombre que le hemos asignado.
Ejemplo: Código Repetido
1public static void main(String[] args) {
2 // ... código
3
4 // Fragmento repetido #1
5 System.out.println("Voy a saludar tres veces:");
6 for (int i = 0; i < 3; i++) {
7 System.out.println("Hola.");
8 }
9
10 // ... más código
11
12 // Fragmento repetido #2
13 System.out.println("Voy a saludar tres veces:");
14 for (int i = 0; i < 3; i++) {
15 System.out.println("Hola.");
16 }
17
18 // ... otro código
19
20 // Fragmento repetido #3
21 System.out.println("Voy a saludar tres veces:");
22 for (int i = 0; i < 3; i++) {
23 System.out.println("Hola.");
24 }
25}Solución: Usar una Función
Cada fragmento de código repetido puede sustituirse por el nombre que le hemos asignado, en nuestro casosaludarTresVeces():
1public static void main(String[] args) {
2 // ... código
3 saludarTresVeces(); // Sustitución por una función
4
5 // ... más código
6 saludarTresVeces(); // Sustitución por una función
7
8 // ... otro código
9 saludarTresVeces(); // Sustitución por una función
10
11 // ... resto del código
12}La función saludarTresVeces() tendrá que definirse, de forma que se especifique el conjunto de instrucciones que la forma:
1public static void main(String[] args) {
2 saludarTresVeces();
3 // ... más código
4}
5
6// Definición de la función
7static void saludarTresVeces() {
8 System.out.println("Voy a saludar tres veces:");
9
10 for (int i = 0; i < 3; i++) {
11 System.out.println("Hola.");
12 }
13}Ubicación de las funciones
main(). Por convención, suele colocarse después.Concepto de Función
Esto representa el concepto de función: un conjunto de instrucciones agrupadas bajo un nombre y con un objetivo común, que se ejecuta al ser invocada.
Sintaxis General
1static tipo nombreFuncion() {
2 // Cuerpo de la función
3 // Instrucciones que se ejecutarán
4}Por ahora, definiremos las funciones static y utilizaremos como tipo la función void, que indica que la función no devuelve nada.
Convención de Nombres (Camel Case)
Habitualmente, los nombres de funciones siguen el estilo Camel Case: los nombres comienzan en minúscula, distinguiendo en los nombres compuestos cada palabra mediante la mayúscula inicial.
1// Ejemplos de nombres de funciones en Camel Case
2suma()
3saludarTresVeces()
4calcularRaizCuadrada()
5mostrarTodosDatosCliente()
6validarContrasena()
7obtenerFechaActual()Terminología Importante
Llamada a la función
Es el nombre de la función, seguido de () paréntesis. Se convierte en una nueva instrucción que podemos utilizar para invocar la función.
1saludarTresVeces(); // Esto es una llamada a la funciónPrototipo de la función
Es la declaración de la función, donde se especifica su nombre, el tipo que devuelve y, entre paréntesis, los parámetros de entrada que utiliza.
1static void saludarTresVeces() // Este es el prototipoCuerpo de la función
Es el bloque de código que ejecuta la función cada vez que se invoca y que aparece entre llaves después del prototipo.
1static void saludarTresVeces() {
2 // Este es el cuerpo de la función
3 System.out.println("Voy a saludar tres veces:");
4 for (int i = 0; i < 3; i++) {
5 System.out.println("Hola.");
6 }
7}Definición de una función
Está formada por el prototipo más el cuerpo de la función.
Ventajas de Usar Funciones
Con esto evitamos:
- La duplicidad del código: Ya que el código se escribe una única vez, en la definición de la función.
- La dificultad en el mantenimiento: Ahora, las modificaciones, en el caso de que sean necesarias, solo se realizan en un lugar: en la definición de la función.
Flujo de Ejecución
El comportamiento de una llamada a una función consiste en:
- Las instrucciones del programa principal se ejecutan hasta que encuentra la llamada a la función.
- La ejecución salta a la definición de la función.
- Se ejecuta el cuerpo de la función.
- Cuando la ejecución del cuerpo termina, retornamos al punto del programa desde donde se invocó la función.
- El programa continúa su ejecución.
Funciones vs Métodos
nextInt() deScanner) en realidad son funciones. Una función y un método son conceptualmente idénticos, la única diferencia está en el nombre, que varía dependiendo del paradigma de programación usado:- Programación estructurada: Se llaman funciones
- Programación orientada a objetos: Se denominan métodos
1public class EjemploFunciones {
2
3 public static void main(String[] args) {
4 System.out.println("Inicio del programa");
5
6 saludarTresVeces(); // Primera llamada
7
8 System.out.println("\nOtra parte del código");
9
10 saludarTresVeces(); // Segunda llamada
11
12 System.out.println("\nFin del programa");
13 }
14
15 // Definición de la función
16 static void saludarTresVeces() {
17 System.out.println("Voy a saludar tres veces:");
18 for (int i = 0; i < 3; i++) {
19 System.out.println("Hola.");
20 }
21 }
22}
23
24// Salida:
25// Inicio del programa
26// Voy a saludar tres veces:
27// Hola.
28// Hola.
29// Hola.
30//
31// Otra parte del código
32// Voy a saludar tres veces:
33// Hola.
34// Hola.
35// Hola.
36//
37// Fin del programaÁmbito de las Variables
En el cuerpo de una función podemos declarar variables, que se conocen como variables locales. El ámbitode estas, es decir, donde pueden utilizarse, es la propia función donde se declaran, no pudiéndose utilizar fuera de ella.
1public static void main(String[] args) {
2 int x = 10; // Variable local del main
3
4 miFuncion();
5
6 // System.out.println(y); // ERROR: 'y' no existe aquí
7}
8
9static void miFuncion() {
10 int y = 20; // Variable local de miFuncion
11
12 System.out.println(y); // OK: 'y' existe aquí
13
14 // System.out.println(x); // ERROR: 'x' no existe aquí
15}Ámbito de variables
main.Variables de Bloque
Nada impide que dentro del cuerpo de una función se utilicen sentencias (if,if-else, bucles, etc.) con sus respectivos bloques de instrucciones, donde a su vez, se pueden volver a declarar nuevas variables que se conocen como variables de bloque, siempre y cuando su nombre no coincida con una variable declarada antes, fuera del bloque, ya que esto producirá un error.
1static void ejemploAmbito() {
2 int x = 10; // Variable local de la función
3
4 if (x > 5) {
5 int y = 20; // Variable de bloque (solo existe dentro del if)
6 System.out.println("x = " + x); // OK: x está disponible
7 System.out.println("y = " + y); // OK: y está disponible aquí
8 }
9
10 System.out.println("x = " + x); // OK: x sigue disponible
11 // System.out.println("y = " + y); // ERROR: y no existe fuera del if
12
13 for (int i = 0; i < 3; i++) {
14 int z = i * 2; // Variable de bloque del for
15 System.out.println(z);
16 }
17
18 // System.out.println(i); // ERROR: i no existe fuera del for
19 // System.out.println(z); // ERROR: z no existe fuera del for
20}1public class EjemploAmbito {
2
3 public static void main(String[] args) {
4 int a = 5;
5 System.out.println("En main, a = " + a);
6
7 funcion1();
8 funcion2();
9
10 // Las variables de funcion1 y funcion2 no existen aquí
11 }
12
13 static void funcion1() {
14 int b = 10; // Variable local de funcion1
15 System.out.println("En funcion1, b = " + b);
16
17 if (b > 5) {
18 int c = 15; // Variable de bloque
19 System.out.println("Dentro del if, c = " + c);
20 }
21
22 // c no existe aquí
23 }
24
25 static void funcion2() {
26 int d = 20; // Variable local de funcion2
27 System.out.println("En funcion2, d = " + d);
28
29 // b, c, y a no existen aquí
30 }
31}| Tipo de Variable | Ámbito | Ejemplo |
|---|---|---|
| Local (función) | Toda la función donde se declara | int x = 10; |
| Bloque (if, for, etc.) | Solo dentro del bloque | if(...) { int y; } |
Paso de Información a una Función
En ocasiones, una función necesita conocer información externa para poder llevar a cabo su tarea. Veamos un ejemplo: la funciónsaludarTresVeces() es conveniente cuando queremos saludar exactamente tres veces. Si deseamos saludar un número distinto de veces, estaríamos obligados a implementar las funciones: unSaludo(),dosSaludos(),cuatroSaludos(), etc.
Es mucho más práctico implementar la función variosSaludos() a la que se le pasa el número de veces que deseamos saludar. De esta manera, si ejecutamosvariosSaludos(7), saludará siete veces y si ejecutamosvariosSaludos(2), lo hará en dos ocasiones.