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-04 08:05:29 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!sn-xit-03!sn-xit-06!sn-post-01!supernews.com!corp.supernews.com!not-for-mail From: "Matthew Heaney" Newsgroups: comp.lang.ada Subject: Re: OO in Ada Date: Fri, 4 Oct 2002 11:05:26 -0400 Organization: Posted via Supernews, http://www.supernews.com Message-ID: References: X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2600.0000 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 X-Complaints-To: abuse@supernews.com Xref: archiver1.google.com comp.lang.ada:29513 Date: 2002-10-04T11:05:26-04:00 List-Id: "Rick Duley" wrote in message news:mailman.1033697703.29112.comp.lang.ada@ada.eu.org... > > 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 | > +-------------------------------------------+ I'm not sure why you're using a factory function to return a pointer to a pen object, but in case that's really what you wanted then you'd have something like: package Pens is type Pen_Type (<>) is tagged limited private; type Pen_Access is access all Pen_Type; function New_Pen (X, Y : Natural; C : Color_Type) return Pen_Access; procedure Move_To (Pen : in out Pen_Type; X, Y : Natural); private type Pen_Type is tagged limited record X, Y : Integer; C : Color_Type; end record; end Pens; > 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| > |-------------------------------------------+ In general, the tagged types in a class should be declared in a hierachy of packages: package Pens.Thick is type Pen_Type is new Pens.Pen_Type with private; type Pen_Access is access Pen_Type; function New_Pen (X, Y : Natural; C : Color_Type; T : Positive) return Pen_Access; procedure Move_To (Pen : in out Pen_Type; X, Y : Natural); private type Pen_Type is new Pens.Pen_Type with record Thickness : Positive; end record; end Pens.Thick; > 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_. Visibility in Ada is determined by the relationship of modules, not types. If you want a derived type to have visibility to the parent from which it is derived, then you need to declare the derived type in a child package. (Note that sometimes you don't want to declare the type in a child package, but this is not one of those times.) > 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. No. Because the type is declared in a child package, then it has visibility to the private part of the parent package. > 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? Indeed, you do labour. All you need to do is declare Thick_Pen in a child package. > 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); > > 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. In C++, I can do this: class C { ... }; bool operator=(const C& lhs, const C& rhs); Why doesn't C++ use the "intuitive syntax"?