Importación de paquetes

Importación de paquetes en Kotlin

Habitualmente en la parte superior de todo programa declaramos el nombre del paquete al que pertenece el archivo utilizando la palabra package. Entre otras cosas, esto proporciona una manera de organizar lógicamente clases y funciones; y desde otros archivos (otras clases y módulos) se puede acceder a este paquete usando la palabra reservada import.

En general, los paquetes permiten agrupar clases relacionadas en un espacio común de nombres que facilita al programador su uso y mantenimiento. Los paquetes agrupan funcionalidades relativas a un tema específico, por ejemplo, para el acceso a bases de datos, interfaces visuales, cifrado de datos, acceso a archivos, comunicaciones en la web, etc. y constituyen una forma muy efectiva de organizar el código en nuestro proyecto o para que otros lo reutilicen.

Por tanto, en Kotlin cada archivo puede tener una declaración de paquete al principio del mismo, y todas las declaraciones (clases, funciones y propiedades) definidas formarán parte de ese paquete. Las declaraciones definidas en otros archivos se pueden usar directamente si están en el mismo paquete pero necesitan ser importados si están en un paquete diferente.

Por ejemplo, un archivo fuente puede comenzar con una declaración de paquete de esta manera:
package com.demo

fun miFuncion() { ... }

class MiClase { ... }

// ...
Y todos los contenidos (como clases y funciones) de este archivo forman parte del paquete declarado (y entonces el nombre completo de la función miFuncion es realmente com.demo.miFuncion y el nombre completo de la clase MiClase es com.demo.MiClase).

Podemos acceder a un paquete desde otro archivo con distintas fórmulas para importar una parte (clases, funciones de orden superior o propiedades) o todo su contenido:
import com.MiClase // ahora MiClase es accesible

import com.demo.* // todo el contenido de 'demo' es accesible
Ante un posible conflicto de nombres podemos utilizar la palabra reservada as:
import com.Test // Test es accesible

import demo.Test as dTest // dTest significa 'demo.Test'

Además de las importaciones explícitas, por defecto en cada archivo se importan varios paquetes básicos que forman parte de la biblioteca estándar de Kotlin, como kotlin.*, kotlin.annotation.*, kotlin.collections.*, kotlin.comparisons.*, kotlin.io.*, kotlin.ranges.*, kotlin.sequences.* y kotlin.text.*, cuyas clases e interfaces están automáticamente disponibles para utilizar.

A modo de ejemplo, vamos a ver cómo crear un paquete y luego acceder a su contenido, para lo que vamos a utilizar el IDE IntelliJ IDEA.

Una vez que hemos creado un proyecto (ver Primer proyecto con IntelliJ IDEA), sobre la carpeta scr hacemos clic en el botón secundario del ratón y seleccionamos New -> Package y en el cuadro de diálogo que aparece escribimos el nombre del nuevo paquete, por ejemplo matematicas.

Ahora sobre esta nueva carpeta 'matematicas' hacemos clic con el botón secundario del ratón y seleccionamos New -> Kotlin File/Class y en el cuadro de diálogo seleccionamos File y escribimos el nombre del nuevo archivo que vamos a llamar funciones (solo el nombre, sin extensión). Al confirmar con el botón 'OK' vemos que dentro de la carpeta matematicas ahora tenemos un archivo llamado funciones.kt con esta línea:
package matematicas
En este archivo vamos a escribir un par de funciones de operaciones aritméticas básicas como sumar y restar (dejando el nombre del paquete en la primera línea), quedando el archivo funciones.kt de esta manera:
package matematicas

fun sumar (valor1: Int, valor2: Int) = valor1 + valor2

fun  restar (valor1: Int, valor2: Int) = valor1 - valor2
Después, desde el archivo principal situado en la carpeta src (habitualmente llamado main.tk) vamos a acceder a las funciones de este paquete utilizando import:
import matematicas.*

fun main () {
    val suma = sumar (15, 6)
    println ("La suma es $suma")
    val resta = restar (21, 4)
    println ("La resta es $resta")
}
Podemos ejecutar el programa y veremos que funciona correctamente.

Puedes probar a eliminar o comentar la línea 'import matematicas.*' y comprobarás que el IDE advierte de que existen errores y concretamente las funciones sumar y restar aparecen en rojo; si ahora intentamos ejecutar el programa devuelve un par de errores:
Error:(3, 16) Kotlin: Unresolved reference: sumar
Error:(5, 17) Kotlin: Unresolved reference: restar
Si ahora hacemos clic sobre la función sumar nos aparece un mensaje emergente con el texto 'matematicas.sumar? Alt+Intro'. Si hacemos caso al IDE y pulsamos esta combinación de teclas vemos que en la primera línea del archivo ahora tenemos:
import matematicas.sumar
También comprobamos que la función sumar ya no aparece en rojo. Repetimos con la función restar y volvemos a tener el programa funcional:
import matematicas.restar
import matematicas.sumar

fun main () {
    val suma = sumar (15, 6)
    println ("La suma es $suma")
    val resta = restar (21, 4)
    println ("La resta es $resta")
}
Podemos utilizar un alias:
import matematicas.restar as menos
import matematicas.sumar as mas

fun main () {
    val suma = mas (15, 6)
    println ("La suma es $suma")
    val resta = menos (21, 4)
    println ("La resta es $resta")
}
También podemos omitir el import explícito de esta manera (aunque no suele ser recomendable si tenemos que acceder en múltiples ocasiones al paquete porque hace el código menos conciso):
fun main () {
    val suma = matematicas.sumar (15, 6)
    println ("La suma es $suma")
    val resta = matematicas.restar (21, 6)
    println ("La resta es $resta")
}
Al escribir el código anterior nos damos cuenta que IntelliJ IDEA nos facilita bastante el trabajo porque según empezamos a escribir mat... el IDE nos sugiere el paquete matemáticas y después de escribir el punto nos sugiere en primer lugar las funciones propias del paquete (restar y sumar) y nos indica los parámetros que admite y su tipo.

Cuando IntelliJ IDEA detecta que existen errores por referencias a clases o funciones no resueltas, ofrece sugerencias sobre la necesidad de importar paquetes que resuelven estos errores y podemos añadirlos rápidamente con el atajo Alt+Intro. Por ejemplo, en la entrada Métodos para concatenar Arrays observamos que importamos la clase Arrays de la biblioteca estándar de Java con:
import java.util.Arrays
Si eliminamos o comentamos esta línea, IntelliJ IDEA nos sugiere hacer una importación para resolver el problema pero al presionar Alt+Intro nos añade esta línea:
import java.util.*
Eso importará todas las clases, interfaces y funciones declaradas en ese paquete, aunque no suele ser lo más recomendado y es preferible hacer importaciones explícitas y limitadas. Pero como en este caso solo queremos acceder a la clase Arrays, podemos borrar el .* de fin línea y al escribir nuevamente el punto, el IDE nos sugiere varias posibilidades entre las que se encuentra Arrays.

Vamos a ver otro ejemplo de un archivo fuente que muestra la sintaxis de la declaración del paquete y la declaración de importación. Para ello vamos a crear dos archivos, ejemplo.kt y rectangulo.kt, ambos formando parte del paquete geometria según esta estructura (se puede usar cualquier otra estructura de directorios para organizar los archivos):

Estructura en IntelliJ IDEA
// archivo rectangulo.kt
package geometria.formas

// importamos Random de la biblioteca estándar de Java
import java.util.Random

// clase Rectangulo con propiedad de tipo booleano
class Rectangulo(val alto: Int, val ancho: Int) {
    val esCuadrado: Boolean
        get() = alto == ancho
}

// función que devuelve un objeto de tipo Rectangulo de parámetros aleatorios
fun crearRectangulo(): Rectangulo {
    val random = Random()
    return Rectangulo(random.nextInt(), random.nextInt())
}
// archivo ejemplo.kt
package geometria.ejemplos

// del paquete geometria.formas solo importamos esta función
import geometria.formas.crearRectangulo

fun main() {
    // la funcion importada devuelve un objeto de tipo Rectangulo
    // que invoca una propiedad de su clase
    println(crearRectangulo().esCuadrado)
}

Comentarios

Entradas populares

Recursos gratis para aprender Kotlin

I/O: entrada y salida de datos en consola

Lectura y escritura de archivos