Article View: comp.lang.eiffel
Article #1280Re: Conflict Between Class-as-Module and Class-as-Type (long)
From: Jos Warmer
Date: Tue, 10 Jan 1989 08:53
Date: Tue, 10 Jan 1989 08:53
111 lines
4724 bytes
4724 bytes
In article <6417@bunny.UUCP> dcr0@bunny.UUCP (David Robbins) writes:
>
>I have three classes named ROOT_CLASS, A, and B, defined as follows:
>
> class ROOT_CLASS
> inherit STD_FILES
> feature
> an_a: A; a_b: B; b_invoked_as_a: A;
> Create is do
> an_a.Create; a_b.Create; b_invoked_as_a := a_b;
> putstring("Calling A.f1: "); an_a.f1;
> putstring("Calling A.f2: "); an_a.f2;
> putstring("Calling B.f2: "); a_b.f2;
> putstring("Calling B.f3 (which is really A.f1): "); a_b.f3;
> putstring("Calling B.f1 through A's interface: "); b_invoked_as_a.f1;
> putstring("Calling B.f2 through A's interface: "); b_invoked_as_a.f2
> end
> end
>
> class A export f1, f2
> inherit STD_FILES
> feature
> f1 is do putstring("I am A.f1"); new_line end;
> f2 is do putstring("I am A.f2"); new_line end
> end
>
> class B export f2, f3
> inherit A rename f1 as f3 redefine f2
> feature
> f2 is do putstring("I am B.f2"); new_line end
> end
>
>Results of Execution --
>
> Calling A.f1: I am A.f1
> Calling A.f2: I am A.f2
> Calling B.f2: I am B.f2
> Calling B.f3 (which is really A.f1): I am A.f1
> Calling B.f1 through A's interface: I am A.f1
> Calling B.f2 through A's interface: I am B.f2
>
>export f1. Since B does not export f1, I would certainly not expect
>"b_invoked_as_a.f1" to succeed. After all, it is trying to call feature f1
>of an instance of B, which does not export any such feature. In fact, B
>does not even possess a feature named f1!
>
This behaviour is correctly defined in eiffel. It is even neccesary to define
this behaviour if you want compile-time checking.
The entity "b_invoked_as_a" has static type A. It is impossible for the
compiler to know the dynamic type of "b_invoked_as_a". So if the compiler has
to check whether some feature is applicable to "b_invoked_as_a", it can only
look at the features of A. If a feature is not redefined, then the definition
from A is used. This choice can only be made at runtime.
The rules are:
The features that may be applied to an entity depend on the static type
of the entity. The actual definition used may depend on the dynamic type.
The call "b_invloked_as_a.f3" will not be allowed by the compiler,
because it is not exported by class A.
This behaviour can also be undesirable when using implementation inheritance,
as I stated in a previously posted article.
++ At page 241 of Bertand Meyer's book an alternate definition is
++ given for STACK2 (page 118): the class FIXED_STACK. It is declared
++ an heir of class ARRAY, instead of a client.
++
++ As far as I can see this definition of FIXED_STACK has a serious
++ safety-leak, as opposed to the definition of STACK2 at page 118.
++
++ Consider the following piece of (pseudo) eiffel code:
++
++ a : ARRAY[INTEGER]; -- declare an entity of type ARRAY
++ f : FIXED_STACK[INTEGER]; -- declare an entity of type FIXED_STACK
++
++ f.Create; -- created a fixed stack
++ f.push(12); -- top of stack is now 12
++
++ a := f; -- allowed, because FIXED_STACK is descendant of ARRAY
++ a.enter(1, 20); -- enter is allowed on ARRAY's
++
++ value := f.top: -- this will deliver value 20, instead of the previously
++ -- entered 12.
++
++ This example shows that any client of FIXED_STACK can manipulate its
++ implementation.
>This behavior violates my expectation of what I tend to call "specification
>inheritance."
Inheritance in eiffel is always inheritance of the complete implementation.
>counterexample to this claim: class B is totally unequipped to handle
>feature f1 (although the Eiffel implementation manages to secretly give B a
>feature named f1, in violation of the semantics of Eiffel).
class B is a descendant of class A, so it IS equipped to handle feature f1.
Jos Warmer
jos@cs.vu.nl
...uunet!mcvax!cs.vu.nl!jos
PS. We have ordered the compiler, but it hasn't arrived yet.
So I can't try anything out. This is not too bad, now I actually
have to *think* about it.
--
Jos Warmer
jos@cs.vu.nl
...uunet!mcvax!cs.vu.nl!jos
Technical Details
Message-ID:
<1884@vlot.cs.vu.nl>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!mcvax!hp4nl!botter!star.cs.vu.nl!josReferences:
<6417@bunny.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!mcvax!hp4nl!botter!star.cs.vu.nl!jos From: jos@cs.vu.nl (Jos Warmer) Newsgroups: comp.lang.eiffel Subject: Re: Conflict Between Class-as-Module and Class-as-Type (long) Message-ID: <1884@vlot.cs.vu.nl> Date: 10 Jan 89 08:53:37 GMT References: <6417@bunny.UUCP> Reply-To: jos@cs.vu.nl (Jos Warmer) Organization: VU Informatica, Amsterdam Lines: 111