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,900edaa189af2033 X-Google-Attributes: gid103376,public From: wheeler@aphrodite.csed.ida.org (David Wheeler) Subject: Re: Ada95 OOP Questions Date: 1996/07/30 Message-ID: <4tl235$a1v@news.ida.org> X-Deja-AN: 171032070 references: <4tf3l4$4hu@masala.cc.uh.edu> <4tgi88$5fi@Masala.CC.UH.EDU> organization: IDA, Alexandria, Virginia newsgroups: comp.lang.ada Date: 1996-07-30T00:00:00+00:00 List-Id: Spasmo (cosc19z5@Bayou.UH.EDU) wrote: (C++ example) : Person p; : p.walk(); : p.talk(); : p.eat(); (Ada example, modified to use a "use" clause) : begin : Walk(P); : Talk(P); : Eat(P); : end Main; : Correct me if I'm wrong on this. So you're still passing parameters : which means that data and subprograms are still 2 different entities : which sorta hurts the abstraction, rather than in say C++ where : you've got a unified object. I'm afraid you haven't got it. Correction, per your request, follows :-). In _BOTH_ C++ _AND_ Ada you pass a parameter. In C++ you say: p.walk(); In Ada you say: walk(p); IN BOTH CASES YOU PASS A PARAMETER. BOTH. BOTH. BOTH. When you say "p.walk()" in C++, "p" is the first parameter! The only difference is that, to dispatch in C++, you use a different syntax and the dispatching parameter is listed in a distinguished position. In C++ the parameter is always called "this". In Ada, any parameter can be a dispatching parameter, and the syntax for calling the method doesn't change. C++ PASSES A PARAMETER. It has to, otherwise how would the C++ operation being called know which object to work with? The different syntax seems to be really throwing you. Don't let it. In fact, if in the Ada example P is of type "Person'Class", and in C++ the operations are all virtual, the two examples above are EXACTLY equivalent and will do EXACTLY the same thing. They'll look at a pointer "hidden" in P to look up the correct "walk" operation for this type, and then dispatch to it, passing a pointer/access value to P as the first parameter. : rather than a unified object that was like a combination of : data and subprograms that enabled it to smoothly simulate an : entity? Data and subprograms are unified, but Ada thinks of structuring in terms of _packages_. An Ada package with a tagged data structure and subprograms using it defines a unified object definition. I think you're not understanding the key role of Ada packages. Packages are the _primary_ Ada structuring mechanism. In Ada, you can't "with" half a package. When you "with" the package, you "with" the whole thing, data structures AND operations. : Also there's another slight difference -- inheritance. From : what I'm seeing, if we wanted to create say a SuperPersons : package that inherited from persons we'd create a new package : called SuperPerson, then we'd with the Persons package, and : provide "wrappers" for everything defined in the Persons : package right? Wrong. If that were true, you wouldn't have inheritance the way most people define the term. Children of tagged types inherit all the operations of their ancestors. : Then we'd of course inherit from the data : types and add in any new functionality that we wanted to, : am I correct? No, you inherit operations, too. Of course, if you don't override the operations in the child types, you get what was defined by the parent. : For example here's a crude idea of what I'm talking about: : with Persons; : package SuperPersons is : type SuperPerson is tagged private; : procedure Walk(SP : SuperPerson); : procedure Talk(SP : SuperPerson); : procedure Eat(SP : SuperPerson); : private : type SuperPerson is new Persons.Person with : record : SuperPowers : Power; : end record; : end SuperPersons; : then all our procedures like Walk, Talk, Eat, etc... would need : to call their predecessors right? For instance: Nope. If you don't override Walk, for example, you'll get the "Walk" operation defined by "Person". : Am I correct or can we in fact inherit operations without manually : providing wrappers for the predecessors? You inherit without manually providing wrappers for the predecessors. That's one of the primary capabilities of Ada 95. Still in doubt? Go to my example, program Small at "http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/small.htm". Click on the package spec for Players -- gee, no operations defined! Where are they defined? Well, Player is a child of Creature, so click on that -- still no operations -- click on its parent, Occupant, and you'll see a whole bunch of operations (and more on its parent, Thing). You get all the operations of your ancestors, and you DON'T have to define the wrappers. Want to see a trivial example of overriding? See Occupant's May_I_Get method and compare it to Item's May_I_Get method. The Get command simply calls May_I_Get, dispatching to whichever version is the correct one for the type. IN SUMMARY: 1. Both C++ and Ada pass parameters to do dispatching. They have to, otherwise you wouldn't know what you're working on. 2. Packages are the key Ada structuring mechanism. 3. Tagged type methods (aka primitive operations) inherit. --- David A. Wheeler Net address: wheeler@ida.org