2013-05-04 72 views
5

不知道这个oop模式被称为什么,但我怎么能在Ada中做同样的模式? 例如下面的代码:如何在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); 

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

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”声明是为时已晚 生成结果的警告:规范应该

+0

我不确定接口,但我知道动态调度基/父包需要在一个单独的包文件中。 – 2017-03-11 00:05:45

回答

6

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

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

关于Interfaces的Ada Rationale章节详细讨论了这一点。

这是一个基于你的问题的工作示例 - 我重命名了一些东西并修复了一些可能在你看到的错误消息中迷失的错误:-)注意添加了一个类型'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! 
4

Java风格的接口在Ada2005推出的“车”的声明后,立即出现:

type Vehicle is interface; 

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

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

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

type Tractor is new Vehicle with null record; 

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

我会离开,其余作为一个练习,你可以阅读更多有关wikibook

+0

这是我尝试过的,但我不知道如何使它工作: – Jossi 2013-05-05 13:07:05

+0

您希望TestVehicle程序能够采用各种车辆,而不仅仅是packageVehicle.Vehicle,所以添加'class: 程序TestVehicle(Vehicle:packageVehicle。 Vehicle'class)为 – egilhh 2013-05-05 14:18:39

+0

您还需要查看您要呼叫的开始功能: 'Ada.Text_IO.Put_Line(packageVehicle.Start(Vehicle));' 或使用虚线符号(Ada2005): 'Ada。 Text_IO.Put_Line(Vehicle.Start);' 另外,TestVehicle不返回一个字符串,所以你不需要在主体中使用put_lines。 – egilhh 2013-05-05 14:24:10

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这个概念被使用了很多的想法。