comp.lang.ada
 help / color / mirror / Atom feed
From: ncohen@watson.ibm.com (Norman H. Cohen)
Subject: Re: Initialization Params for Controlled Types
Date: 14 Nov 1994 21:19:30 GMT
Date: 1994-11-14T21:19:30+00:00	[thread overview]
Message-ID: <3a8k92$10rk@watnews1.watson.ibm.com> (raw)
In-Reply-To: 1994Nov10.152352.27015@unix.brighton.ac.uk

In article <1994Nov10.152352.27015@unix.brighton.ac.uk>,
je@unix.brighton.ac.uk (John English) writes: 

|> Norman H. Cohen (ncohen@watson.ibm.com) wrote: 
...
|> : You can look at this as a problem with the operation Open or a problem
|> : with the hierarchy.  If you view it as a problem with the hierarchy, a
|> : solution is to introduce a new abstract class, say Universal_Account,
|> : that declares the operations that truly are meaningful for ALL bank
|> : accounts, and derive BankAccount and CurrentAccount from
|> : Universal_Account.  Open is not one of these operations.  Two distinct
|> : versions of Open would be declared for the two derived types.
|>
|> Changing the hierarchy only postpones the problem: Open will end up as
|> a primitive of CurrentAccount, and any derivation from CurrentAccount
|> will therefore inherit it.  Open is indeed not one of those universally
|> sensible operations, so it needs to be provided as a non-primitive, and
|> it needs to be provided anew for every derivation.  And each new version
|> will have to call its parent's version of Open to do the parent-part
|> specific initialisation.  This is where it gets messy and error-prone.

This is a more general problem that arises with OOP in any language: 
Often the need arises to define a new class B that has MOST, BUT NOT ALL
of the features of some other class A.  The problem is that the author of
A, not having been omnisicient, failed to recognize it as a special case
of a more general problem for which other special cases would arise in
the future.  If you don't have the authority to modify the definition of
class A, you end up duplicating a lot of code.  If you do have such
authority, you can FACTOR the common features of A and B into a new class
C, redefine A as a specialization of C, and define B as another
specialization of C.

In your example, CurrentAccount is A and the unanticipated derivation
from CurrentAccount that you hypothesize is B.  (Had the derivation been
anticipated, an abstract class playing the role of C--having all the
features of CurrentAccount meaningful even for specializations of current
accounts, but not features such as Open--would have been written in the
first place, and a concrete class would have been defined by deriving
from this abstract class and adding an appropriate Open operation.

|> And of course, there is no way in 9X to force Open to be called and you
|> have to take extra care (e.g. an Initialised flag) to prevent it being
|> called more than once.  C++ constructors are a neat solution to these
|> problems -- they are always called exactly once per object, they are
|> not inherited, they automatically call the base class constructor, and
|> they can have parameters.  Ada 9X requires a lot more effort to avoid
|> subtle errors IMHO.

I'm confused now about whether you're envisioning Open as a function or a
procedure.  (It's been a while and I don't have the full example at
hand.)  As others have pointed out, a function with a classwide result
subtype,

   function Open_Current_Account (...) return Account'Class;

will not be inherited.  However, calls on functions are not intrinsically
associated with objects.  Your remark about exactly one call on open per
object sounds like an initialization PROCEDURE.  This can be provided by
controlled types.  Like C++ constructors, the Initialize procedure of a
controlled type is called once per object, and can be parameterized using
discriminants.  By default, a C++ constructor is not inherited, but a
default constructor that implicitly calls the base-class constructor is
implicitly created, which amounts to pretty much the same thing.  In Ada
9X the parent's Initialize procedure is not implicitly invoked by the
derived type's Initialize procedure, but it is straightforward to make an
explicit call.

--
Norman H. Cohen    ncohen@watson.ibm.com



  parent reply	other threads:[~1994-11-14 21:19 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-10-27  9:44 Initialization Params for Controlled Types Angel Alvarez
1994-10-27 14:27 ` Tucker Taft
1994-11-04 13:44   ` John English
1994-11-04 22:16     ` Norman H. Cohen
1994-11-05 15:01       ` Cyrille Comar
1994-11-07 10:32         ` John English
1994-11-07  9:08       ` John English
1994-11-10 15:23       ` John English
1994-11-11 10:44         ` Robb Nebbe
1994-11-14 21:19         ` Norman H. Cohen [this message]
1994-11-14 18:35           ` Robert I. Eachus
1994-11-16 21:45           ` Matt Kennel
1994-10-27 23:06 ` Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox