comp.lang.ada
 help / color / mirror / Atom feed
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



  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