Oop 如何在Ada中实现接口?

Oop 如何在Ada中实现接口?,oop,interface,ada,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 functio

我不知道这个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”的声明太晚了
生成器结果警告:规范应在Ada2005中引入Java风格接口声明后立即出现:

type Vehicle is interface;
接口上的任何操作都必须是抽象的:

function start(Self : Vehicle) return String is abstract;
继承接口时,必须将其指定为父接口,并实现 为接口定义的操作(“重写”告诉编译器父级必须有相应的“开始”。但是关键字是可选的):


我将把其余部分留作练习,您可以在

中阅读更多关于接口的内容。需要注意的关键是“一个接口类型的所有用户定义的基本子程序都应该是抽象子程序或空过程。”(),即,您不能定义将接口本身作为参数的子程序(是的,我知道这与Java不同。)这就是为什么在TestVehicles声明中出现错误的原因

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

Ada基本原理一章对此进行了详细讨论

下面是一个基于您的问题的工作示例--我重命名了一些东西,并修复了一些可能在您看到的错误消息中丢失的错误:-)注意添加了一个实例化车辆接口的类型“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;
编译和运行:

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

下面是程序的工作版本,使用指针(Ada中称为“access”)。与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的新手,我可能有一些错误,但我知道这个概念在哪里被大量使用。

这是我尝试过的,但我不知道如何使它工作:你希望TestVehicle程序能够容纳所有类型的车辆,而不仅仅是packageVehicle。Vehicle,所以添加“class:procedure TestVehicle”(Vehicle:packageVehicle.Vehicle'class)您还需要查看正在调用的启动函数:
Ada.Text\IO.Put\u Line(packageVehicle.start(Vehicle));
或使用点符号(Ada2005):
Ada.Text\IO.Put\u Line(Vehicle.start)
此外,TestVehicle不返回字符串,因此您不需要在主体中使用put_行。我不确定接口,但我知道动态调度时,基本/父包需要位于单独的包文件中。
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;