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,98f446539174ef31 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: OOP & Packages in Ada Date: 1998/02/01 Message-ID: X-Deja-AN: 321170575 Content-Transfer-Encoding: 8bit References: <6asp37$q8b$1@Masala.CC.UH.EDU> <6b1atp$ngp$1@Masala.CC.UH.EDU> Content-Type: text/plain; charset=ISO-8859-1 Organization: Estormza Software Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 1998-02-01T00:00:00+00:00 List-Id: In article <6b1atp$ngp$1@Masala.CC.UH.EDU>, wanker@exploited.barmy.army wrote: >Well, I'm thinking along somewhat different lines. Rather than >creating an "improvement" over a parent, we are simply making >a new type. For example, let's use the cliched example of a >biological organism: > >Let's assume the parent package/object has the following type: > Mammal > >And the methods: > Eat > Sleep > Breed > >Now let's say we declare a child with the following type: > Dog > >And the method: > Bark > >Plus, the Dog, being a type of Mammal also uses the method Eat, >Sleep, and Breed. > >Now, in this case we want the Eat, Sleep, and Breed methods >to appear to be part of the Dogs package, because otherwise >the users of our package would have to know our inheritance >hierarchy, and also what methods are over-ridden and >what aren't. That's too much to have the user worry about, >and to me seems to hurt the abstraction. If you want just the "primitive" operations of the type to be directly visible to clients of the child package, then the answer is, yes, they are already directly visible. This sort of thing was already true in Ada 83: derivation from another type makes all the "primitive" operations of the parent type implicitly declared at the point of declaration of the derived type. That means Eat, Sleep, and Breed are directly visible in the Dog package. To call the Eat operation of Dog, the client need only refer to the Dog package, not the parent package (containing type Mammal). >I mean to the user, A dog can eat, sleep, and breed as well >as bark, so it makes perfect sense to have these guys as >part of the dog package. They are. >I guess it's debatable as to whether or not it's desirable >to have people know that a Dog is derived from Mammal, but >I don't feel it necessary. Well then, the use of inheritence is debatable. The only reason to use inheritence at all is because you want to enable polymorphic behavior. If you never manipulate objects of type Mammal'Class, then why bother publically deriving from Mammal? Better is to create a new root type (here, Dog), and then privately inherit (if necessary) from Mammal. To do otherwise is to create unnecessary coupling. >Furthermore, the situation gets >really hideous if we have a pretty hefty inheritance chain >like: > > >Object (Appearance) > Organism (Reproduction) > Animal (Locomotion) > Mammal (Fur_Thickness) > Dog (Bark) > Collie (Grooming) > > >Where Object has a method Appearance, and Organism is derived >from object and it has a method Reproduction, and Animal is derived >from Organism, etc... You should never have deep inheritence hierarchies in Ada. If you do, then you are doing something wrong. Here's why. Ada is not a pure object-oriented language. It was made for systems programming, specifically designed to implement systems that have high reliability requirements. In such systems, only minimal use (if any) of heap is allowed. That is why Ada (and C++) has value semantics by default. Other languages, say Java or Eiffel, have reference semantics by default. Every Dog object goes on the heap. In fact every object (the exceptions are "expanded" objects in Eiffel) goes on the heap, and gets automatically garbage collected. This ubiquitous use of the heap is fine, but makes those languages unsuitable for the class of systems for which Ada was designed. But this seemingly innocuous decision to make objects have value semantics has over-arching consequences for design of software systems in Ada (and C++). When I declare an object like this declare My_Dog : Collie; begin the compiler has to know how much space to allocate for My_Dog at compile time. This makes this module *very* sensitive to changes in ancestor types. Every time you touch an ancestor package, the compiler is going to have to recompile *all* the packages containing the declarations of types in the Collie hierarchy. Pure object oriented languages don't have this problem, because the representation of all objects is the same: it's just a pointer, whose size is known statically. That's why the style of type design in pure object oriented languages favors deep hierarchies (as a reuse mechanism), because there's essentially no compilation penalty. But we don't have this luxury in Ada systems. Any change near the root of a hierarchy is going to have a potentially massive ripple-effect, because the compiler has to adjust the size of all statically declared objects of any descendent type. Sadly, many Ada (and C++) programmers haven't caught on to this idea. They create deep hierarchies because "that's how you do it in Eiffel or Smalltalk, you know, in a pure object oriented language," but then they have to recompile the universe every time they make a change. Worse, they turn around and blame Ada, and say "Ada compiles are slow." This isn't an Ada problem, it's a programmer problem. That is why I admonish you to create hierarchies that are broad and shallow, and avoid hierarchies that are deep and narrow. If you want reuse, don't use inheritence to effect it, use aggregation (or possibly private inheritence). Use public inheritence because you want polymorphic behavior, because you want to allow different representations for a classwide object. I will say it again: do not create deep inheritence hierarchies in Ada. If you do, you're not thinking in Ada, and you're doing something very very wrong. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant (818) 985-1271