Dont know what this oop pattern is called but how can I do the same pattern in Ada? For example this code:
interface Vehicle{
string function start();
}
class Tractor implements Vehicle{
string function start(){
return "Tractor starting";
}
}
class Car implements Vehicle{
string function start(){
return "Car starting";
}
}
class TestVehicle{
function TestVehicle(Vehicle vehicle){
print( vehicle.start() );
}
}
new TestVehicle(new Tractor);
new TestVehicle(new Car);
my failed attempt in Ada: How to fix it properly?
with Ada.Text_IO;
procedure Main is
package packageVehicle is
type Vehicle is interface;
function Start(Self : Vehicle) return String is abstract;
end packageVehicle;
type Tractor is new packageVehicle.Vehicle with null record;
overriding -- optional
function Start(Self : Tractor) return string is
begin
return "Tractor starting!";
end Start;
type Car is new packageVehicle.Vehicle with null record;
overriding -- optional
function Start(Self : Car) return string is
begin
return "Car starting!";
end Start;
procedure TestVehicle(Vehicle : packageVehicle.Vehicle) is
begin
Ada.Text_IO.Put_Line( "Testing a vehicle" );
Ada.Text_IO.Put_Line( Start(Vehicle) );
end;
Tractor0 : Tractor;
Car0 : Car;
begin
Ada.Text_IO.Put_Line( TestVehicle(Tractor0) );
Ada.Text_IO.Put_Line( TestVehicle(Car0) );
end Main;
Compiler says: Builder results warning: declaration of "TestVehicle" is too late Builder results warning: spec should appear immediately after declaration of "Vehicle"
The key thing to be aware of is "All user-defined primitive subprograms of an interface type shall be abstract subprograms or null procedures." (Ref) I.e. you can't define a subprogram that takes the interface itself as a parameter (yes, I know this is different from Java.) This is why you're getting the error on the TestVehicles declaration.
Essentially, you have to define a type that implements the interface(s), then work with that type.
The Ada Rationale chapter on Interfaces discusses this in some detail.
Here's a working example based on your question--I renamed some things and fixed a couple errors that were probably getting lost amongst the error messages you were seeing :-) Note the addition of a type 'Concrete_Vehicles' that instantiates the Vehicle interface.
with Ada.Text_IO; use Ada.Text_IO;
procedure Interface_Test is
package Package_Vehicle is
type Vehicle is interface;
function Start(Self : Vehicle) return String is abstract;
end Package_Vehicle;
type Concrete_Vehicles is abstract new Package_Vehicle.Vehicle with null record;
type Tractor is new Concrete_Vehicles with null record;
overriding -- optional
function Start(Self : Tractor) return string is
begin
return "Tractor starting!";
end Start;
type Car is new Concrete_Vehicles with null record;
overriding -- optional
function Start(Self : Car) return string is
begin
return "Car starting!";
end Start;
procedure TestVehicle(Vehicle : Concrete_Vehicles'Class) is
begin
Ada.Text_IO.Put_Line( "Testing a vehicle" );
Ada.Text_IO.Put_Line( Start(Vehicle) );
end;
Tractor0 : Tractor;
Car0 : Car;
begin
TestVehicle(Tractor0);
TestVehicle(Car0);
end Interface_Test;
Compiling and running:
[22] Marc say: gnatmake interface_test.adb
gcc -c interface_test.adb
gnatbind -x interface_test.ali
gnatlink interface_test.ali
[23] Marc say: ./interface_test
Testing a vehicle
Tractor starting!
Testing a vehicle
Car starting!
Java-style interfaces was introduced in Ada2005:
type Vehicle is interface;
Any operations on the interface must be abstract:
function start(Self : Vehicle) return String is abstract;
When inheriting the interface, you must specify it as a parent, and implement the operations defined for the interface ("overriding" tells the compiler that the parent must have a corresponding "start". The keyword is optional, however):
type Tractor is new Vehicle with null record;
overriding -- optional
function start(Self : Tractor) return String;
I will leave the rest as an exercise, you can read more about interfaces in the wikibook
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With