From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Dynamic binding
Date: Fri, 13 Apr 2012 22:55:59 +0200
Date: 2012-04-13T22:55:59+02:00 [thread overview]
Message-ID: <55tfbsnll3t0$.1hx68o0qdhb90$.dlg@40tude.net> (raw)
In-Reply-To: 32a3d08f-7b48-46e2-b8cf-004acb6e40a3@d4g2000vbn.googlegroups.com
On Fri, 13 Apr 2012 13:13:17 -0700 (PDT), Katarina Olsson wrote:
> I have a question about dispatching in Ada. As we know, methods in
> java are always called on their objects. Let say that we have a class
> Parent with methods a() and b(), where a calls b like this:
>
> class Parent{
>
> public void a() {
> System.out.println("parent a");
> b();
> }
>
> public void b(){
> System.out.println("parent b");
> }
> }
>
> Consider now the class Child extends Parent. It has overridden the b()
> method like this:
>
> class Child extends Parent{
>
> @Override
> public void b(){
> System.out.println("child b");
> }
>
> }
>
> When creating a Child object and calling the a() method,
>
> Child c = new Child();
> c.a();
>
> the output will be the following on stdout:
>
>>>parent a
>>>child b
>
> I have now attempted to reproduce the corresponding case in Ada.
You cannot. Ada's OO is properly typed. Java's model is not. The behavior
of A evidently shall not depend on whether Parent is a part of Child or
not. I.e. it shall always print:
parent a
parent b
This is what you get in Ada. To summarize:
1. The operation A is defined on the type Parent. Period. Overriding
changes nothing here. You override B for *another* type: Child. That does
not influence any inherited operations. I.e. the operation A inherited from
Parent stay intact.
2. Dispatch happens just once. When the specific type is determined through
dispatch, then it is known. End of story.
> This should correspond to the previous java case, shouldn't it? In any
> case it seems to me that calling the A procedure on the Child Object,
> would render the output
>
>>>parent a
>>>parent b -- (instead of child b)
>
> Do I need to try again or have I understood it correctly? And if I
> have, how would I best reproduce the java behaviour?
Java's behavior is re-dispatch.
But from the design point of view there are three choices (two good and one
not so good).
1. A proper design. If A calls to B which depends on the specific type from
the class (dispatches), then A is likely same for all instances from that
class. In this case you just declare it so:
type Parent is ...
procedure A (X : in out Parent'Class); -- You need no pointers in Ada
procedure B (X : in out Parent);
...
procedure A (X : in out Parent'Class) is -- A does not dispatch!
begin
Put_Line ("A is always A");
X.B; -- This dispatches
end A;
procedure B (X : in out Parent) is
begin
Put_Line ("Parent's B");
end B;
--------------
type Child is new Parent with ...;
overriding procedure B (X : in out Child);
procedure B (X : in out Child) is
begin
Put_Line ("Child's B");
end B;
This will print for Parent'Class which is a Child object:
A is always A
Child's B
A is called class-wide in Ada. All calls from it will be dispatching.
Class-wide operations represent in Ada the concept of generic programming:
operations defined for a whole set of types (the class).
2. Another properly typed variant is when both A and B are methods
(primitive operations in Ada terms), and you override both A and B in
Child:
type Parent is ...
procedure A (X : in out Parent); -- Dispatches
procedure B (X : in out Parent); -- Dispatches
--------------
type Child is new Parent with ...;
overriding procedure A (X : in out Child);
overriding procedure B (X : in out Child);
3. Java's design (re-dispatch). You can have it in Ada, but because
re-dispatch is unsafe (potentially breaks the implementation of the parent
type), you must be explicit about it. So that the reader could see the
hazard:
type Parent is ...
procedure A (X : in out Parent); -- You need no pointers in Ada
procedure B (X : in out Parent);
...
procedure A (X : in out Parent) is -- This dispatches
begin
Put_Line ("Parent's A");
Parent'Class (X).B; -- Now it dispatches again,
-- caution: type conversion!
end A;
This will print for a Child object:
Parent's A
Child's B
In this example X of the type Parent is converted to a class, which makes
the result to remember that it was of the type Child in its life before A
was called.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
next prev parent reply other threads:[~2012-04-13 20:56 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-13 20:13 Dynamic binding Katarina Olsson
2012-04-13 20:55 ` Dmitry A. Kazakov [this message]
2012-04-14 6:41 ` Niklas Holsti
2012-04-14 7:39 ` Simon Wright
2012-04-14 8:58 ` Dmitry A. Kazakov
2012-04-15 12:04 ` AdaMagica
-- strict thread matches above, loose matches on Subject: below --
2012-04-13 20:11 Katarina Olsson
2012-04-14 8:43 ` Georg Bauhaus
2012-04-14 17:17 ` Simon Wright
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox