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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham 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,UTF8 Received: by 10.204.143.143 with SMTP id v15mr1097475bku.8.1336206523966; Sat, 05 May 2012 01:28:43 -0700 (PDT) Path: h15ni200912bkw.0!nntp.google.com!news2.google.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx02.iad01.newshosting.com!newshosting.com!news2.euro.net!xlned.com!feeder1.xlned.com!npeer.de.kpn-eurorings.net!npeer-ng0.de.kpn-eurorings.net!feed.news.schlund.de!schlund.de!news.online.de!not-for-mail From: Felix Krause Newsgroups: comp.lang.ada Subject: Re: OOP in Ada: Alternatives for "protected" scope Date: Sat, 5 May 2012 10:28:43 +0200 Organization: 1&1 Internet AG Message-ID: References: <1vn9nv4aqm9a3.1tqzc91idjlbs$.dlg@40tude.net> <17kcn9g4qeg7j.5xole2f4bwbj$.dlg@40tude.net> NNTP-Posting-Host: port-92-203-5-22.dynamic.qsc.de Mime-Version: 1.0 X-Trace: online.de 1336206523 30391 92.203.5.22 (5 May 2012 08:28:43 GMT) X-Complaints-To: abuse@einsundeins.com NNTP-Posting-Date: Sat, 5 May 2012 08:28:43 +0000 (UTC) User-Agent: Unison/2.1.7 X-Received-Bytes: 5615 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Date: 2012-05-05T10:28:43+02:00 List-Id: On 2012-05-04 22:00:41 +0000, Dmitry A. Kazakov said: > On Fri, 4 May 2012 20:48:53 +0200, Felix Krause wrote: > >> On 2012-05-03 21:56:51 +0000, Dmitry A. Kazakov said: >>> >>> 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. >> >> Compared to my version (with redispatching issues fixed), this >> alternative enforces a weaker contract. > > I don't like re-dispatch, it is a design bug to me. Well, this is probably a question of personal preference. At least Ada lets one choose whether to redispatch or not. > >>> 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 >> >> So, to be able to use these visibility scopes, the class hierarchy must >> follow the layout of the package hierarchy. > > That depends on what you mean. Classes (types constituting them) stretch > across packages, as types don't live in the vacuum. > > Ada separates types and visibility. Comparing to other languages it is a > great advantage. I understand that you see it differently, but that is > because you haven't yet accustomed to the Ada's model. I think you're right here. I don't want to question Ada's model, I just want to see how it can be applied to OOP-related problems. > Note that Ada has another (inferior) model as well. It can be seen in Ada > protected and task types. They are mess. It was a mistake. > >> I think this is a >> disadvantage for some reasons: >> >> * Given the scenario that you use an Ada software library containing >> tagged types, you have to subclass these types in child-packages within >> the package layout of the library. > > Only if you want to access private, i.e. implementation-dependent, stuff. > Note that when a package depends on the implementation details of another > package, this constitutes a tight coupling. Ada requires the programmer to > manifest this design decision in the form of a parent-child package > relation. This IMO is a good thing. You cannot access the implementation > details if you don't state your intention making it visible for the reader. > Note also that this decision is all on the child's side. In the competing > model, any derived type always get access, so the decision is on the parent > type side. This is a bad design because it forces the programmer to make > his choice early and, maybe, it does a wrong person. Hmm, good point. I see "protected" / abstract methods rather as an additional interface of the class type than as "implementation-dependent stuff". While it's true that changing the implementation of a type by overriding its operations implies tight coupling, I don't think this is neccessarily true for abstract methods. But I see that if abstract methods are an interface of the type, these should rather be placed in the public part. >> I for myself would rather want to >> place my code in the package hierarchy of my application. > > That is not a problem, you can rename packages. Didn't think about that, good point. >> * It doesn't work with generics: >> >> generic >> -- ... >> package P is >> type A is tagged private; >> -- … >> end P; >> >> package Q is >> package P_Instance is new P (...); >> >> type B is new P_Instance.A with private; >> end P.Q.R; > > You use a generic child: > > generic > package P.Q is > type B is new A with private; > private > ... -- You have visibility of P's private here > end P.Q; Yes, but that's not what I wanted. Let's have a more specific example using orthogonal inheritance: package P is type A is tagged private; -- ... end P; generic type Base is new A with private; package P.Extend is type Extended is new Base with private; -- ... end P.Extend; package P.Q is type B is new A with private; -- ... end P.Q; package P.Q.R is package B_Extend is new P.Extend (Base => B); type C is new B_Extend.Extended with private; end P.Q.R; (I actually have some code with this structure.) I cannot possibly access the private part of P.Extend in P.Q.R - although I'm extending the class defined there. I cannot layout the packages in a way that lets me access both P.Extend's and P.Q's private part in P.Q.R. I admit that this is a rare case and in my code I don't need to share any private information of P.Extend.