如何在Ada中实现界面?

时间:2013-05-04 17:23:39

标签: oop interface ada

不知道这个oop模式被调用了什么,但我怎么能在Ada中做同样的模式? 例如这段代码:

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);

我在Ada失败的尝试: 如何妥善解决?

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;

编译说: 生成器结果警告:声明“TestVehicle”为时已晚 构建器结果警告:声明应在声明“Vehicle”后立即出现

3 个答案:

答案 0 :(得分:6)

要注意的关键是“接口类型的所有用户定义的基本子程序都应该是抽象子程序或空程序。” (Ref)I.e。你不能定义一个将接口本身作为参数的子程序(是的,我知道这与Java不同。)这就是你在TestVehicles声明中得到错误的原因。

基本上,您必须定义一个实现接口的类型,然后使用该类型。

关于Interfaces的Ada Rationale章节对此进行了详细讨论。

这是一个基于你的问题的工作示例 - 我重命名了一些东西并修复了一些错误,这些错误可能会在您看到的错误消息中丢失:-)请注意添加一个类型'Concrete_Vehicles'来实例化Vehicle接口

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;

编译并运行:

[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!

答案 1 :(得分:4)

Ada2005中引入了Java风格的接口:

type Vehicle is interface;

界面上的任何操作都必须是抽象的:

function start(Self : Vehicle) return String is abstract;

继承接口时,必须将其指定为父接口,并实现 为接口定义的操作(“覆盖”告诉编译器父进程必须具有相应的“start”。关键字是可选的,但是):

type Tractor is new Vehicle with null record;

overriding -- optional
function start(Self : Tractor) return String;

我将剩下的作为练习,你可以在wikibook

中阅读更多关于界面的内容

答案 2 :(得分:0)

以下是程序的工作版本,使用指针(在Ada中称为“访问”)。您不需要使用接口的实现来使用接口,就像在Java示例中一样,这是面向对象编程和多态的主要要点。

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 : Access packageVehicle.Vehicle'class) is
begin
    Ada.Text_IO.Put_Line( "Testing a vehicle" );
    Ada.Text_IO.Put_Line( Vehicle.Start );
end;

Tractor0 : access Tractor'Class := new Tractor;
Car0 : access Car'Class := new Car;

begin

TestVehicle(Tractor0);
TestVehicle(Car0);

end Main;
PS:我是Ada的新手,我可能错了,但我有https://github.com/raph-amiard/ada-synth-lib的想法,这个概念被大量使用了。