codecamp

Ada私有类型和有限专用类型

私有类型   

    到目前为止,我们见过的在程序包内定义的数据类型,只要使用with语句,我们都能对它进行任意的处理,没有什么限制。这在有些情况下,会引起麻烦。比方说创建了一套函数库,如果在该函数库里的数据类型能被用户自由处理----创建新类型,加减乘除运算.....用户又频繁使用的话,会使用户程序相当依赖于这些数据类型,而函数库的创建者为了提高效率或其它什么原因,需要改变这些数据类型---取消,重写或合并,这时用户所写的程序将会遇到很大的麻烦,要么就用旧版的函数库,要么就改写自己的程序-----都是不怎么好的做法。在 Unix 下有 C 语言经验的朋友应该对这所谓的“兼容性”深有体会----系统很无聊的包含了很多只为了兼容性考虑的数据类型、函数,为了移植性,开发稍大一点的软件就多了一些很无谓的“痛苦”。私有类型就是为这种情况产生的:在程序包外,对私有类型数据只能执行 := 和 = 操作,如有其它操作也是程序包内定义的。这样的好处是私有类型不会被滥用,相关的子程序都是程序包创建者定义的,而不是用户。考虑一下下面的账号管理的例子,具体函数实现略,只是象征性的说明一下问题:

000 -- filename:account.ads
001 package Accounts is
002    type account is private; -- 具体声明在后面
003     My_Account : constant account;
004    procedure withdraw(account:in out account; amount :in Positive);
005    procedure deposit (account:in out account; amount :in Positive);
006    function create(account:in out account;account_id :Positive) return Boolean; 
007    function cancel(account:in out account;account_id :Positive) return Boolean;
008    function balance(account: in out account) return Integer;
009 private 
010    type account is 
011    record
012        account_id : positive;
013        balance : integer;
014    end record;
015 My_Account:constant account := (78781, 122); 
016 end accounts;

    过程 withdraw 和 deposit 对帐号进行取款和存款操作,create 和 cancle 对帐号进行创建和注销,balance 返回当前账号的存款额。实际应用中为了提高效率,这种类型的函数库很有可能需要随时升级,使用了私有类型,用户层的麻烦少了不少。

    私有类型 account 先简略地声明为类型 private,它的具体声明跟在保留字 private 后,接下去就跟普通数据类型声明一样。account 类型的数据可以在该程序包外包括在主程序中创建,但对它的操作只能是赋值、相等比较及该函数包定义的操作;在该程序包内,则能对私有类型进行任意操作,就好像它不是私有类型一样。在这个例子里,我们还创建了一个 account 类型的常量 My_Account,注意它的声明方式:先是不完全的声明,再在private 部份给出完整声明。不管怎样,用户只能通过函数说明知道有这么个私有类型,却不能过多的使用它。

有限专用类型

    如果嫌私有类型的 := 和 = 这两个默认操作也多余,则使用有限专用类型。如声明上例的account为有限专有类型:

type account is limited private;

    其它方面与私有类型一样,只是声明略有不同。对这种数据类型的操作只能由该程序包完全定义,没有了其它默认操作。

    有时类型定义中还会出现单独的 limited,没有 private,这表示该类型是限制类型,赋值等操作不能作用于该类型变量,但不是“私有”的。

Ada程序包的概述
Ada子单元和私有子单元
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }