Josh
Josh

Reputation: 383

How to set up and derive a type from an abstract tagged record?

I'm having some difficulties getting my head around inheritance in Ada, and with some syntax.

My goal is to derive from an abstract type with a record, and use a different data type in the record field. Here's what I've been able to compile:

type Base is abstract new Parent.ParentType with record
    X:Access_Type;
end record

type Child is new Base with record
    n:Integer;
end record;

But I don't want to have this additional n field, I'd like to have X be an integer in the child type. I can't get the compiler to be happy with it. Something like the following is what I want:

type Base is abstract new Parent.ParentType with tagged record
    X:Access_Type;
end record;

type Child is new Base with record
    X:Integer;
end record;

Unfortunately, I can't figure out how to tag the base type which I think would allow me to reassign the X field. (Without tagging, the compiler complains of conflicting declarations.)

Can someone shed some light on this? I'm quite new to OO programming in general and I'm finding Ada's type approach more confusing than the usual class approach.

Upvotes: 3

Views: 1680

Answers (3)

trashgod
trashgod

Reputation: 205885

I'm not sure what problem you are trying to solve by changing the type of X in a derived type. As suggested in Ada 95 Rationale: II.1 Programming by Extension, extension of a tagged type adds components to those inherited from the base type. As @Martin comments, 4.3.2 Extension Aggregates allow "specifying a value or subtype for an ancestor of the type." As shown in the tutorial Extension Aggregates, this includes "an extension of a private ancestor type," as @Simon shows. Also consider that you can specify parameters for a derived type using discriminants.

Addendum: It may help to understand that Ada's support for common object-oriented programming principles is not limited to tagged types.

Upvotes: 4

user571138
user571138

Reputation:

Are you sure you are not just wanting to nest some records ?

   type Base is abstract new Parent.Parent_Type with record
      X : Float;
   end record;

...

type child_rec is 
  X : integer;
end record;

...

   type Child is new Bases.Base with record
      C : Child_Rec;
   end record;

Which will allow you to refer to

My_Base.X;

and

My_Base.C.X;

Of course this can be done without any of the OO features too....

Upvotes: 4

Simon Wright
Simon Wright

Reputation: 25511

Base has to be tagged, because you can't say is abstract new Parent.Parent_Type unless Parent.Parent_Type is tagged, and that means that any derived type such as Base must be too.

The problem is that, as you have it, any code that can see Child could see two Xs; the one in Base and the one in Child. The compiler won't let you be ambiguous; when others read your code and see My_Child.X, how will they know which X you meant?

One way round this would be to make the full declaration of Base private, so that there's only one visible possibility for My_Child.X:

package Bases is
   type Base is abstract new Parent.Parent_Type with private;
private
   type Base is abstract new Parent.Parent_Type with record
      X : Float;
   end record;
end Bases;

with Bases;
package Children is
   type Child is new Bases.Base with record
      X : Integer;
   end record;
end Children;

Upvotes: 3

Related Questions