Los
paquetes exportan mediante una interfaz bien definida tipos, objetos y operaciones y permiten ocultar su implementación, lo que proporciona al programador
tipos abstractos de datos∞ y
subprogramas∞ de manera transparente.
Los paquetes de Ada proporcionan:
Especificación y cuerpo
El paquete consta de especificación (parte visible) y cuerpo (implementación que se oculta) y pueden compilarse por separado.
La sintaxis de su especificación es la siguiente:
especificación_paquete ::=
package∞ [ identificador_unidad_padre . ] identificador
is∞
{ declaración_básica }
[
private∞ { declaración_básica } ]
end∞ [ [ identificador_unidad_padre . ] identificador ] ;
La sintaxis del cuerpo de un paquete es la siguiente:
cuerpo_paquete ::=
package∞ body∞ [ identificador_unidad_padre . ] identificador
is∞
[ parte_declarativa ]
[
begin∞
secuencia_de_sentencias
[
exception∞
manejador_de_excepción
{ manejador_de_excepción } ] ]
end∞ [ [ identificador_unidad_padre . ] identificador ] ;
Un paquete permite agrupar declaraciones y subprogramas relacionados.
Ejemplos
Por ejemplo, para implementar una pila de enteros:
package∞ Pila_Enteros
is∞ -- Especificación.
procedure∞ Poner (Elem: Integer); -- Interfaz.
function∞ Quitar
return∞ Integer; -- Interfaz.
end∞ Pila_Enteros;
package∞ body∞ Pila_Enteros
is∞ -- Cuerpo.
Max :
constant∞ := 100; -- Se ocultan las variables locales.
Pila:
array∞ (1..Max)
of∞ Integer; -- Se ocultan las variables locales.
Cima: Integer
range∞ 0..Max; -- Se ocultan las variables locales.
procedure∞ Poner (Elem: Integer)
is∞ -- Implementación.
begin∞
Cima := Cima + 1;
Pila (Cima) := Elem;
end∞ Poner;
function∞ Quitar
return∞ Integer
is∞ -- Implementación.
begin∞
Cima := Cima - 1;
return∞ Pila(Cima + 1);
end∞ Quitar;
begin∞
Cima := 0; -- Inicialización.
end∞ Pila_Enteros;
En este caso, se tiene una interfaz que proporciona acceso a dos subprogramas para manejar la pila, aunque también se podrían haber exportado tanto tipos como objetos, constantes, tareas e incluso otros paquetes. Por ejemplo:
package∞ Sobre_Días
is∞
type∞ TDía
is∞ (LUN, MAR, MIE, JUE, VIE, SAB, DOM);
subtype∞ TDíaLaborable
is∞ TDía
range∞ LUN..VIE;
SiguenteDía:
constant∞ array∞ (TDía)
of∞ TDía :=
(MAR, MIE, JUE, VIE, SAB, DOM, LUN);
end∞ Sobre_Días;
En este caso, el paquete no necesitaría cuerpo.
Dependencia entre especificación y cuerpo
La especificación del paquete y el cuerpo pueden compilarse por separado. Mediante este encapsulamiento, ahora no es posible desde fuera modificar, por ejemplo, el valor de la cima de la pila, pues este objeto no es visible. Así se evita un mal empleo de la pila por alguien que pueda no conocer su implementación.
Si la especificación de un paquete contiene la especificación de un subprograma, entonces, el cuerpo del paquete debe contener el correspondiente cuerpo del subprograma. Sin embargo, pueden existir subprogramas dentro del cuerpo del paquete que no se declaren en su especificación, serían, por tanto, internos.
Destacar que dentro del cuerpo del paquete se inicializa el valor de la cima de la pila (después de begin). Esto sucede cuando se elabora el paquete. Si no necesita ninguna sentencia, se puede omitir el begin.
Declaración y visibilidad
Los paquetes se pueden declarar en cualquier parte declarativa, es decir, en un bloque, subprograma o dentro de otro paquete. En el caso del ejemplo, para utilizar la pila de números enteros, se podría hacer así:
declare∞
N: Integer;
package∞ Pila_Enteros
is∞
-- ...
end∞ Pila_Enteros;
begin∞
Pila_Enteros.Poner (15);
N := Pila_Enteros.Quitar;
end∞;
Dentro del paquete se puede llamar a Poner o a Pila_Enteros.Poner, pero fuera del paquete únicamente se puede llamar a dicho procedimiento de la forma Pila_Enteros.Poner. Además, las variables Max, Pila y Cima no son visibles.
Importación de paquetes
Para la utilización de los paquetes desde otras unidades de compilación, se definen estas dos cláusulas:
Manual de referencia de Ada