comp.lang.ada
 help / color / mirror / Atom feed
From: ncohen@watson.ibm.com (Norman H. Cohen)
Subject: Re: Initialization Params for Controlled Types
Date: 4 Nov 1994 22:16:42 GMT
Date: 1994-11-04T22:16:42+00:00	[thread overview]
Message-ID: <39ebsa$129i@watnews1.watson.ibm.com> (raw)
In-Reply-To: 1994Nov4.134412.10010@unix.brighton.ac.uk

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

|> There is one subtle danger with using procedures as "constructors".
|> Imagine the following: 
|>   type BankAccount is tagged private;
|>   procedure Open (Account : in out BankAccount;
|>                Name    : in String);
|>
|> Here Open opens a bank account in a particular name.  Now if you
|> derive a new type CurrentAccount from BankAccount to produce a
|> BankAccount that allows overdrafts, you might have this: 
|>   type CurrentAccount is new BankAccount with private;
|>   procedure Open (Account   : in out CurrentAccount;
|>                Name      : in String;
|>                Overdraft : in Money);
|>
|> Here's where the danger is: the first procedure (Open for BankAccount)
|> is a primitive of BankAccount and will be inherited by CurrentAccount.
|> It's therefore possible to initialise a CurrentAccount as if it were
|> a BankAccount, which might leave the overdraft limit uninitialised: 
|>   C : CurrentAccount;
|>   ...
|>   Open (C, "Fred Bloggs");  -- oops!
|>
|> Okay, you can provide a default overdraft limit of 0.00, so this is
|> not an entirely convincing example; the point is that there is a
|> danger here which is non-obvious, since you might forget that there
|> is a second Open for CurrentAccounts which is provided due to inheritance.

There is a good reason the example is not convincing: It violates the
principle that the inheritance hierarchy should reflect an IS-A
relationship.  CurrentAccount should be derived from BankAccount only if
a "current account" is a special kind of "bank account".  If it is, then
it should have all the properties of bank accounts--including the ability
to open it by specifying just a name.  After all, when you add
CurrentAccount to the class rooted at BankAccount, you are asserting that
all the primitive operations of BankAccount can be applied to
BankAccount'Class objects with any tag.

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.

|> C++ sidesteps this problem by making constructors non-inheritable.
|> The only way to accomplish this in 9X is to make sure that Open isn't
|> a primitive (e.g. by shoving it in a child package) which is fairly
|> painful.

Note that the danger of an inadvertent error could be avoided in Ada 9X
by making the constructor a function returning a BankAccount value: 

   function New_Bank_Account (Name: String) return BankAccount;

Then the version inherited by CurrentAccount would be abstract.  Calls on
the inherited version would be illegal, thus alerting the programmer to
the fact that something is amiss.

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



  reply	other threads:[~1994-11-04 22:16 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 [this message]
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
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