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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c9a5d6b3975624e1 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-10-03 19:55:51 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!cyclone.bc.net!newsfeed.telusplanet.net!ps01-chi1!news.webusenet.com!cyclone1.gnilink.net!wn11feed!worldnet.att.net!bgtnsc05-news.ops.worldnet.att.net.POSTED!not-for-mail Message-ID: <3D9D02F3.9090600@worldnet.att.net> From: Jim Rogers User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:0.9.4) Gecko/20011128 Netscape6/6.2.1 X-Accept-Language: en-us MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: OO in Ada References: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Date: Fri, 04 Oct 2002 02:55:50 GMT NNTP-Posting-Host: 12.86.37.162 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc05-news.ops.worldnet.att.net 1033700150 12.86.37.162 (Fri, 04 Oct 2002 02:55:50 GMT) NNTP-Posting-Date: Fri, 04 Oct 2002 02:55:50 GMT Organization: AT&T Worldnet Xref: archiver1.google.com comp.lang.ada:29507 Date: 2002-10-04T02:55:50+00:00 List-Id: Rick Duley wrote: > Hi all > > I believe that I am the last surviving academic Ada programmer in Perth, > Western Australia and I am in need of some help. I am having problems > coming to terms with the rationale behind Object Oriented programming in > Ada and there is no-one I know in Perth to talk to. I'm hoping you folk > won't mind giving me a hand. > > Perhaps I had better start by explaining my (mis-) understanding of the > general principle of inheritance. > > Suppose I have defined an object Pen to have the form: > > +-------------------------------------------+ > | Pen | > +-------------------------------------------+ > | X : Integer; | > | Y : Integer; | > | Color : Color_Type; | > +-------------------------------------------+ > | procedure Move_To(This : in out Pen; | > | X : in Natural; | > | Y : in Natural); | > | -- move the pen to the specified location | > | -- without drawing | > | | > | procedure Draw_To(This : in out Pen; | > | X : in Natural; | > | Y : in Natural); | > | -- draw a line from the current location | > | -- to (X,Y) using the pen's | > | -- current color. the pen's location | > | -- moves to (X,Y) | > | | > | function New_Pen(X : Natural; | > | Y : Natural; | > | Color : Color_Type) | > | return Pen_Access; | > | -- returns access to an initialised Pen | > +-------------------------------------------+ > > This object should be initialised by New_Pen and all the functionality > it should need should be supplied by the other two methods. Of course, > if you want to change Pen Colour in midstream you would have to provide > the functionality to do so but let's keep this simple so I can get a > handle on it ;) > > Extension of this class to Thick_Pen should, according to me, result in > a class having the form: > > +-------------------------------------------+ > | Thick_Pen | > +-------------------------------------------+ > | X : Integer; | > | Y : Integer; | > | Color : Color_Type; | > | Thickness : Positive; | > +-------------------------------------------+ > | --=== inherited from Pen_Class ===-- | > | procedure Move_To(This : in out Pen; | > | X : in Natural; | > | Y : in Natural); | > | -- move the pen to the specified location | > | -- without drawing | > | | > | procedure Draw_To(This : in out Pen; | > | X : in Natural; | > | Y : in Natural); | > | -- draw a line from the current location | > | -- to (X,Y) using the pen's | > | -- current color. the pen's location | > | -- moves to (X,Y) | > | | > | function New_Pen(X : Natural; | > | Y : Natural; | > | Color : Color_Type) | > | return Pen_Access; | > | -- returns access to an initialised Pen | > | | > | --=== new in Thick_Pen_Class ===-- | > | procedure Move_To(This : in out Thick_Pen;| > | X : in Natural; | > | Y : in Natural); | > | -- move the pen to the specified location | > | -- without drawing | > | | > | procedure Draw_To(This : in out Thick_Pen;| > | X : in Natural; | > | Y : in Natural); | > | -- draw a line from the current location | > | -- to (X,Y) using the pen's | > | -- current color. the pen's location | > | -- moves to (X,Y). The | > | -- vertical thickness of the pen is given | > | -- by Thickness. | > | | > | function New_Thick_Pen | > | (X : Natural; | > | Y : Natural; | > | Color : Color_Type; | > | Thickness : in Positive) | > | return Thick_Pen_Access; | > | -- returns access to initialised Thick_Pen| > |-------------------------------------------+ > > I would expect all the class attributes, the data variables, to be > accessed by the methods of the derived class with the overloading > providing the polymorphism. My problems start when this doesn't happen. > > 1. All the texts I can find which deal in any degree at all with OO in > Ada teach that the tagged record in an object declaration should be > 'private'. When you follow this line, a derived class does not have > direct access to the object attributes of the base class, i.e. > _there_is_no_inheritace_. If you want direct access to the private members of a tagged type you must create that tagged type in a child package. > > 2. To provide the derived class with access to the object attributes > of the base class I have to create user-defined methods in the base > class. This has two effects: > a) the object attributes of the base class are now effectively > public, i.e. accessible (through the user-defined methods) to any client > module through 'with' and 'use' - which effectively negates the act of > making them private in the first place; > b) having to provide accessibility in this manner emphasises the > fact that inheritance did not occur. > This approach is commonly taught for Java, but not always viewed as a *good thing*. It does allow you to provide subprograms that enforce state rules about the data that cannot be enforced with simple public access. The problem is that most people do not enforce state in these subprograms, resulting in the effect you describe in (a) above. > 3. If the tagged record in the base class is left public and the > derived class is in a child package of the package defining the base > class, then the base class attributes are accessible to the derived > class. So far so good :) However, if in a program 'use'ing the child > package of 'Thick_Pen' (and not mentioning the base package of 'Pen') I > make a call to the routine 'Draw' with an actual parameter of the type > 'Pen' I get a compiler error message to the effect that 'Draw' is not > visible. In other words, Thick_Pen has not inherited the operation Draw > for 'Pen' Again, _there_is_no_inheritace_. Just how are you defining your derived class? It should be defined as something like: type Thick_Pen is new Pen with private; .... private type Thick_Pen is new Pen with record Thickness : Positive; end record; > > 4. Further along that line, Thick_Pen does not inherit the type Pen so > I cannot declare a Pen (or Pen_Access) unless I 'with' and 'use' the > package in which Pen is declared. This means that making the package in > which Thick_Pen is declared a child of the package in which Pen is > declared totally useless. _There_is_no_inheritance_! > > I have to say that this is the first time in pretty near a decade I have > been writing in and teaching with Ada that Ada hasn't come up with the > goods. Do I labour under some serious misunderstanding, do I have > something terribly wrong? It would really help if you showed your offending Ada code. I still suspect you are not extending your tagged type correctly. Until you do that you will not get inheritance. > > 5. One final thing (for this time anyway ;), why is it that that Ada > does not use the intuitive 'object.method' syntax for making calls to > and object. This would mean that (in the case described in section 3) > the call would read > > Pen.Draw(To_X => n, To_Y => n); Not quite. Pen is the name of the tagged type. It would look more like: My_Pen : Pen; My_Pen.Draw(To_X => n, To_Y => n); There are several reasons why this form was not done in Ada. In C++ this syntax is good for virtual functions but illegal for static functions. This causes nasty problems in C++ template construction. C++ (and Java) forbid dispatching based upon the return type of a function. This is one of the side effects of the 'object.method' notation. Ada avoids all these problems with its notation. Recent discussions about future version of C++ have strongly suggested that the 'object.method' notation has a low return on investment and should be phased out by allowing virtual functions to be called in the same way as static functions. > > and with inheritance this would be accessible through the child package > declaring Thick_Pen. While I'm okay with using the existing syntax, I > feel the 'object.method' syntax is more intuitive and in line with OO > thinking. If there are people working on Ada0x then maybe we should be > putting this forward for consideration. > > Jim Rogers