如何在Ada中实现界面?

Jos*_*ssi 5 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);
Run Code Online (Sandbox Code Playgroud)

我在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;
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*c C 6

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

实质上,您必须定义实现接口的类型,然后使用该类型.

关于接口的Ada Rationale章节详细讨论了这一点.

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

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;
Run Code Online (Sandbox Code Playgroud)

编译和运行:

[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!
Run Code Online (Sandbox Code Playgroud)


egi*_*lhh 5

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

type Vehicle is interface;
Run Code Online (Sandbox Code Playgroud)

接口上的任何操作都必须是抽象的:

function start(Self : Vehicle) return String is abstract;
Run Code Online (Sandbox Code Playgroud)

继承接口时,您必须将其指定为父级,并实现为该接口定义的操作(“覆盖”告诉编译器父级必须有相应的“开始”。不过,该关键字是可选的):

type Tractor is new Vehicle with null record;

overriding -- optional
function start(Self : Tractor) return String;
Run Code Online (Sandbox Code Playgroud)

我将剩下的作为练习,您可以在wikibook 中阅读有关接口的更多信息