From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,12a63150f4f961a X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,BIG5 Received: by 10.68.230.98 with SMTP id sx2mr3859000pbc.1.1336082222819; Thu, 03 May 2012 14:57:02 -0700 (PDT) Path: pr3ni729pbb.0!nntp.google.com!news1.google.com!goblin2!goblin.stu.neva.ru!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: OOP in Ada: Alternatives for "protected" scope Date: Thu, 3 May 2012 23:56:51 +0200 Organization: cbb software GmbH Message-ID: <1vn9nv4aqm9a3.1tqzc91idjlbs$.dlg@40tude.net> References: Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: KA5xyyPKkGZLxk9XJsNqLQ.user.speranza.aioe.org Mime-Version: 1.0 X-Complaints-To: abuse@aioe.org User-Agent: 40tude_Dialog/2.0.15.1 X-Notice: Filtered by postfilter v. 0.8.2 Content-Type: text/plain; charset="big5" Content-Transfer-Encoding: 8bit Date: 2012-05-03T23:56:51+02:00 List-Id: On Thu, 3 May 2012 23:27:55 +0200, Felix Krause wrote: > I have some abstract class A, defined in package P_A. This class > provides some functionality as procedure Do_Something. Now there is > some calculation to be done while execution Do_Something which cannot > be defined in A. Therefore, it is left to the specific child classes of > abstract class A to implement that calculation. The code might look > like this: In that case Do_Something cannot be a primitive operation or else the operation called from it must re-dispatch. > package P_A is > type A is abstract tagged private; > > procedure Do_Something (Object : in out A); > > function Calculate (Object : in out A) return Integer is abstract; This is illegal in Ada 95-2005. > private > -- define A here... > end P_A; > > package body P_A is > procedure Do_Something (Object : in out A) is > Var : Integer; > begin > -- some useful code here�K > > -- let the specific child class define this calculation > Var := Calculate (Object); This is wrong, it should have been Var := Calculate (A'Class (Object)); or else Do_Something should be declared class-wide: procedure Do_Something (Object : in out A'Class); > -- some more useful code here... > end Do_Something; > end P_A; > > The function Calculate should only be used internally. I do not see a > good way to enforce this with Ada: I do not want to move it to P_A's > private part, because child classes of A should not be required to be > located in sub-packages of P_A. (It's also forbidden for an abstract > function to reside in the private part.) If Do_Something varies in children they should override it. The reusable parts common for all children can be factored out as a private class-wide operation. All children having access to private operations must be declared in children packages. package P is type A is abstract tagged private; procedure Do_Something (Object : in out A) is abstract; private ... procedure Do_Prologue (Object : in out A'Class); procedure Do_Epilogue (Object : in out A'Class); end P; package P.Q is type B is new A with private; overriding procedure Do_Something (Object : in out B); ... end P.Q; package body P.Q is procedure Do_Something (Object : in out B) is begin Do_Prologue (Object); ... -- Do specific calculations Do_Epilogue (Object); end Do_Something; end P.Q; > In languages like Java and C#, there is a "protected" scope to cope > with this situation. This is exactly what Ada's private is. The correspondence goes as follows: "Public" <-> Ada' public operation "Protected" <-> Ada's private operation "Private" <-> An operation defined in the package body -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de