FechaVersiónDescripción
19/09/20211.0.0Versión inicial
07/10/20242.0.0Se añade Dart

1 Introducción

La mejor forma de crear y mantener un programa grande es construirlo a partir de piezas más pequeñas o módulos. Cada uno de los cuales es más manejable que el programa en su totalidad.

⚡ Las funciones (subprogramas) son utilizadas para evitar la repetición de código en un programa al poder ejecutarlo desde varios puntos de un programa con sólo invocarlo.

El concepto de función, también conocido como método, es una forma de encapsular un conjunto de instrucciones dentro de una declaración específica (llamada generalmente SUBPROGRAMA o FUNCIÓN), permitiendo la descomposición funcional y la diferenciación de tareas.

Utilidad principal de las funciones:

Características de las funciones:

 

2 Declaración de una función

Declarar una función simplemente significa crearla para que luego pueda ser llamada (utilizada) desde otro lugar del código de nuestro programa. Una función se estructura en cabecera y cuerpo.

La cabecera se declara en una sola línea y se compone de:

El cuerpo es un bloque de código entre llaves { … } que se ejecutará cuando desde otra parte del código utilicemos la función.

[Modif_de_función] Tipo_devuelto Nombre_de_función (lista_de_parámetros)
{
...
}

Ejemplos de funciones:

 

Este es un ejemplo muy sencillo de una función llamada ‘imprimeHolaMundo’, que no tiene parámetros de entrada (no hay nada entre los paréntesis) y no devuelve ningún valor (indicado por void). Cuando la llamemos lo único que hará será escribir por pantalla el mensaje “Hola mundo”.

 

Esta función se llama ‘imprimeHolaNombre’, tiene como parámetro de entrada un dato String llamado ‘nombre’ y no devuelve nada. Cuando la llamemos imprimirá por pantalla el texto “Hola “ seguido del String nombre que se le pase como parámetro.

Esta función se llama ‘doble’, tiene como parámetro de entrada un dato int llamado ‘a’ y devuelve un dato de tipo int. Cuando la llamemos calculará el doble de ‘a’ y lo devolverá (con el return).

Esta función se llama ‘multiplica’, tiene dos parámetros de entrada de tipo int llamados ‘a’ y ‘b’ y devuelve un dato de tipo int. Cuando la llamemos calculará a*b y lo devolverá (con el return).

Esta función se llama ‘maximo’, tiene dos parámetros de entrada de tipo double llamados ‘valor1’ y ‘valor2’ y devuelve un dato de tipo double. Cuando la llamemos calculará el máximo entre ‘valor1’ y ‘valor2’ y lo devolverá.

Esta función se llama ‘sumaVector’, tiene un parámetro de entrada tipo int[] (un vector de int) llamado ‘v’ y devuelve un dato tipo int. Cuando la llamemos recorrerá el vector ‘v’, calculará la suma de todos sus elementos y la devolverá.

 

Es importante saber que las funciones se declaran dentro de ‘class’ pero fuera del ‘main’.

En este programa tenemos 7 funciones: imprimeHolaMundo, imprimeHolaNombre, doble, multiplica, máximo y main. Sí, el ‘main’ donde siempre has programando hasta ahora es en efecto una función, pero un poco especial: ‘main’ es la función principal, el punto de inicio de un programa.

Es obligatorio que todo programa Java tenga una función main. Si te fijas, es una función que recibe como parámetro un String[] (vector de String) y no devuelve nada (aunque podría devolver un int). El por qué de esto lo veremos más adelante.

Las 6 funciones que hemos declarado arriba del main por sí solas no hacen nada, simplemente están ahí esperando a que sean llamadas (utilizadas), normalmente desde el propio main, como podéis observar dentro de este con la función maximo que se invoca dentro de la llamada a la función de sistema printf.

 

3. Llamada a una función

Las funciones pueden ser invocadas o llamadas desde cualquier otra función, incluida ella misma. Sí, una función puede llamar a cualquier otra función, y una función puede llamarse a sí misma.

De todos modos por ahora llamaremos funciones solo desde la función principal ‘main’. Así es más sencillo de aprender al principio.

Cuando se invoca una función el flujo de ejecución salta a la función (pasándole los parámetros si los hubiera), se ejecutan las instrucciones de la función y por último vuelve al punto que llamó a la función para seguir ejecutándose.

Las funciones se invocan con su nombre, pasando la lista de parámetros entre paréntesis. Si no tiene parámetros han de ponerse los paréntesis igualmente. Si la función devuelve un valor, para recogerlo hay que asignarlo a una variable o utilizarlo de algún modo (pueden combinarse funciones en expresiones e incluso pasarlo a otras funciones).

 

Ejemplo utilizando algunas de las funciones del apartado anterior:

 

Ejemplo: Programa con una función que suma dos números.

Salida:

ejecucion_suma

 

Ejemplo: Programa con una función que determina si un número es par o impar.

Salida:

par

 

4. Ámbito de las variables

Una función solo puede utilizar las variables de ámbito local, es decir, sus propias variables (los parámetros de la cabecera y las variables creadas dentro de la función). Cuando una función se ejecuta se crean sus variables, se utilizan y cuando la función termina se destruyen las variables.

Por todo ello una función no puede utilizar variables que estén fuera de ella, y fuera de una función no es posible utilizar variables de la propia función. A esta característica se le llama encapsulación y permite que las funciones sean independientes entre sí, facilitando el diseño de programas grandes y complejos.

Veamos uno fragmento de código y el resultado de la ejecución:

Resultado de la ejecución para un n1 igual a 20:

ambito_variable

 

⚡ Técnicamente sí es posible que una función utilice variables que están fuera de ella, pero eso lo veremos en futuras unidades cuando aprendamos Programación Orientada a Objetos.

 

5. Parametros: Paso por valor y paso por referencia

Existen dos tipos de parámetros y es importante comprender la diferencia.

Salida:

Variables_por_valor

 

Salida:

Variables_por_referencia

📣 IMPORTANTE: Como un parámetro de tipo objeto es una referencia al objeto String o Array que está fuera de ella, si se le asigna otro objeto se pierde la referencia y ya no se puede acceder al objeto fuera de la función. Aunque Java permite hacerlo, no se aconseja hacerlo.
⚠ NO SE ACONSEJA HACER ESTE TIPO DE COSAS.

 

6. Devolución de un valor

⚡ Los métodos pueden devolver valores de tipo básico o primitivo (int, double, boolean, etc.) y también de tipo objeto (Strings, arrays, etc.).

En todos los casos es el comando return el que realiza esta labor. En el caso de arrays y objetos, devuelve una referencia a ese array u objeto.

 

7. Funciones en Dart

Dart es un verdadero lenguaje orientado a objetos, por lo que incluso las funciones son objetos y tienen un tipo, el tipo Function. Esto significa que las funciones pueden asignarse a variables o pasarse como argumentos a otras funciones. También puede llamar a una instancia de una clase como si fuera una función.

Para las funciones que contienen una sola expresión, puede usar una sintaxis abreviada usando la notación => también llamada 'arrow syntax'. La sintaxis => expr es una forma abreviada de { return expr; }

 

Una función puede tener dos tipos de parámetros: requeridos y opcionales. Los parámetros requeridos se enumeran primero, seguidos de cualquier parámetro opcional. Los parámetros opcionales nombrados también se pueden marcar como @required.

Parámetros opcionales

Los parámetros opcionales pueden ser posicionales o nombrados, pero no ambos a la vez.

Parámetros opcionales con nombre

Al definir una función que tenga parámetros con nombre se usa la forma {param1, param2,…} para especificar los parámetros nombrados:

Al llamar a una función, se especifican los parámetros con nombre usando paramName: valor:

Para indicar que un parámetro es obligatorio usamos la anotación @required en el parámetro. Al usar la anotación el analizador de código del compilador pueden comprobar si no se suministra el argumento en la construcción y lanzar un aviso.

 

Parámetros opcionales por posición

Para indicar que uno o varios parámetros son posicionales se usan los corchetes []:

 

Parámetros con valor por defecto

 

Para definir valores por defecto en parámetros con nombre y posicionales se usa =. Los valores por defecto deben ser constantes en tiempo de compilación. Si no se proporciona un valor por defecto, el valor predeterminado es null: