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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c83a22003c320b45 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-11-10 11:03:27 PST Newsgroups: comp.lang.ada Path: nntp.gmd.de!xlink.net!howland.reston.ans.net!pipex!uknet!dcs.gla.ac.uk!unix.brighton.ac.uk!je From: je@unix.brighton.ac.uk (John English) Subject: Re: Initialization Params for Controlled Types Message-ID: <1994Nov10.152352.27015@unix.brighton.ac.uk> Organization: University of Brighton, UK X-Newsreader: TIN [version 1.2 PL2] References: <1994Nov4.134412.10010@unix.brighton.ac.uk> <39ebsa$129i@watnews1.watson.ibm.com> Date: Thu, 10 Nov 1994 15:23:52 GMT Date: 1994-11-10T15:23:52+00:00 List-Id: Norman H. Cohen (ncohen@watson.ibm.com) wrote: : 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. I've had to think about this one for a while -- I didn't find it convincing but couldn't figure out why. The idea is that yes, a current account is a kind of bank account. BankAccount is an "idealised" bank account -- no transaction will be refused, no charges will be made, no interest is payable. Classes like CurrentAccount can then extend this into something more realistic and so can SavingsAccount etc. All these account types will have the common properties inherited from BankAccount (deposit, withdraw, check balance, print statement...) However, extending a class involves adding extra members to it and these must be initialised somehow. If it isn't possible to do this with a simple default in the type declaration, you have to call an initialisation routine. The question is really whether Open should be a primitive. Each different derivation of BankAccount will have been extended in a different way and so will require different initialisation, using different parameters. It's quite hard to prevent Open being a primitive (it needs declaring elewhere, so you have to provide an elsewhere for it) but it's incorrect to consider it as an operation which can be applied to any BankAccount'Class since it is responsible for class-specific initialisation. : 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. 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. -- ------------------------------------------------------------------------------- John English | Thoughts for the day: Dept. of Computing | - People who live in windowed environments University of Brighton | shouldn't cast pointers E-mail: je@brighton.ac.uk | - In C++ only your friends can access your Fax: 0273 642405 | private parts -------------------------------------------------------------------------------