概述(Overview)
多子程序封裝在一個文件里過于龐大,且分類不清,這時就使用了程序包(package),作為一種分組機制,將子程序歸類封裝成獨立的單元。Ada 的程序包機制主要受 Pascal 及 70 年代時的軟件工程技術(shù)影響。當時很主要的一項革新就是軟件包的概念。軟件包使一個大程序分離成了多個單元,使軟件維護更加方便,可重用性也更高,是結(jié)構(gòu)化編程思想中必不可少的一部份。
軟件包并不關(guān)心程序是如何運行的,而是在于理解程序是如何構(gòu)成的以及維護性。Ada 的程序包是定義一堆相關(guān)實體(如數(shù)據(jù)類型、運算符、子程序)的最基本單元,也是使用最常用的編譯單元之一。本章里我們介紹程序包的常見用法,更多的內(nèi)容,如類屬程序包,請參見后面的章節(jié)。
程序包的聲明(Package Declaration)
程序包一般分為兩部份,聲明部分和執(zhí)行部份。聲明部份聲明子程序、變量等實體,他們通常被稱為資源;而執(zhí)行部份則是聲明部分中實體的實現(xiàn)。它們的擴展名一般情況下分別為 ads 和 adb。為了省力點,我們就直接將上一章的overload 做個處理,將"+"和Put封裝在程序包內(nèi),這樣程序包說明如下:
000 --filename:overload.ads
001 package Overload is
002 type Vector is array (1 .. 5 ) of Integer;
003 function "+"(left,right:Vector) return Vector;
004 procedure Put (Item : Vector) ;
005 end Overload;
從這個例子,我們應(yīng)該知道了程序包說明的格式:
package packgae_name is
statements;
end package_name;
statemets就是數(shù)據(jù)類型、變量、常量、子程序的聲明。
程序包的主體部份(Package Body)
僅僅有說明部份,程序包還沒什么用處,還要有它的主體部份,即說明部份的具體實現(xiàn)。主體部份可以包含創(chuàng)建數(shù)據(jù)類型、子程序、變量、常量。它的格式為:
package body packgae_name is
statements1;
[begin]
statements2;
end package_name;
statements1 是創(chuàng)建子程序、數(shù)據(jù)類型、變量、常量的語句,一般情況下是說明部份的具體實現(xiàn);[begin]是可選的,它后面的statement2 是程序包的初始化語句,在主程序執(zhí)行前開始執(zhí)行。
所以上例 overload 的主體部分為:
000 -- filename:overload.adb
001 with Ada.Integer_Text_IO; use Ada.Integer_text_IO;
002 package body Overload is
003 function "+"(left,right:Vector) return Vector is
004 result : Vector ;
005 begin
006 for i in left'range loop
007 result(i) := left(i) + right(i);
008 end loop;
009 return result;
010 end "+";
011 procedure Put (Item : Vector) is
012 begin
013 for i in Item'range loop
014 Put (Item(i));
015 end loop;
016 end Put;
017 end Overload;
這里我們沒有使用可選的 [begin] statement2,因為沒有必要做一些初始化操作。下面是一些注意點:
1.主體部分內(nèi)的資源不能被其它程序包所引用,會引起編譯錯誤。
2.假如好幾個程序包都有初始化語句,執(zhí)行順序是不確定的。
3.所有說明部份內(nèi)的資源可以被其主體部份直接使用,無須 with 和 use 語句。
程序包的使用(Using Package)
如同我們先前使用 Ada.Text_IO 一樣,使用程序包要使用 with 和 use。use 可以不用,但這樣的話使用程序包麻煩很多,如 Put ,就要使用 Ada.Text_IO.Put這種詳細寫法;use 使編譯器自動在軟件包中尋找相匹配的子程序和其它資源?,F(xiàn)在將 overload 的主程序給出:
000 -- filename: main.adb
001 with Overload; use Overload;
002 procedure Main is
003 a,b,c:Vector;
004 begin
005 a := (1,2,3,4,5);
006 b := (1,2,3,4,5);
007 c := a + b;
008 Put (c);
009 end Main;
編譯 main.adb,overload.adb,overload.ads 所得的程序和以前的效果也一樣。
一般情況下,with 和 use 語句在程序的首部,但 use 語句也可以在程序內(nèi)部(with 語句則不能),如:
000 -- filename: main.adb
001 with Overload;
002 procedure Main is
003 use Overload;
004 a,b,c:Vector;
005 begin
006 a := (1,2,3,4,5);
007 b := (1,2,3,4,5);
008 c := a + b;
009 Put (c);
010 end Main;
這種用法很常見,特別是使用類屬程序包時。以后我們會見到這方面的其它實例。
使用軟件包時要注意一下變量、常量等名稱的問題,如果有相同的名稱,就需要詳細寫出所期望的資源名稱,如程序包 Ada.Text_IO 的 Put 要寫為 Ada.Text_IO.Put。如果在 Overload 的聲明部份也加一個變量a(2,3,5,6,8),則聲明部份為:
000 --filename:overload.ads
001 package Overload is
002 type Vector is array (1 .. 5 ) of Integer;
003 a: Vector := (2,3,5,6,8);
004 function "+"(left,right:Vector) return Vector;
005 procedure Put (Item : Vector) ;
006 end Overload;
同時我們希望主程序?qū)蓚€不同的a分別與b相加,則 Overload 中的 a 要表示為 Overload.a,主程序變?yōu)椋?/p>
00 -- filename: main.adb
001 with Overload; use Overload;
002 with Ada.Text_IO; use Ada.Text_IO;
003 procedure Main is
004 a,b,c:Vector;
005 begin
006 a := (1,2,3,4,5);
007 b := (1,2,3,4,5);
008 c := a + b;
009 Put (c);
010 New_Line;
011 c := Overload.a + b; -- Overload.a 表示程序包 Overload中的變量 a
012 Put (c);
013 New_Line;
014 end Main;
明確資源的位置在很多地方都是需要的,都是為了防止相同名稱引起混淆。
更多建議: