2013-05-04 3 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); 

моя неудачная попытка в 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; 

Компилятор говорит: Результаты Builder предупреждение: декларация «TestVehicle» слишком поздно результаты Builder предупреждение: спецификации должны появиться сразу после объявления «Vehicle»

+0

Я не уверен в интерфейсах, но я знаю, что с динамической диспетчеризацией базовый/родительский пакет должен находиться в отдельном файле пакета. – 2017-03-11 00:05:45

ответ

6

Главное, чтобы быть в курсе, «Все определяемые пользователем примитивные подпрограммы типа интерфейса должны быть абстрактными подпрограммами или нулевыми процедурами ». (Ref) I.e. вы не можете определить подпрограмму, которая берет сам интерфейс как параметр (да, я знаю, что это отличается от Java.) Вот почему вы получаете ошибку в объявлении TestVehicles.

По существу, вы должны определить тип, который реализует интерфейс (-ы), а затем работать с этим типом.

Глава Aada Обоснование на Interfaces обсуждает это в деталях.

Вот рабочий пример, основанный на вашем вопросе. Я переименовал некоторые вещи и исправил пару ошибок, которые, вероятно, терялись среди сообщений об ошибках, которые вы видели :-) Обратите внимание на добавление типа «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

+0

Вы хотите, чтобы процедура TestVehicle принимала все виды транспортных средств, а не только упаковку. Vehicle'class) – egilhh

+0

Вам также нужна видимость для функции запуска, которую вы вызываете: 'Ada.Text_IO.Put_Line (packageVehicle.Start (Vehicle));' или использовать пунктирную нотацию (Ada2005): 'Ada. Text_IO.Put_Line (Vehicle.Start); ' Кроме того, TestVehicle не возвращает строку, поэтому вам не понадобятся put_lines в основном корпусе. – egilhh

0

Ниже приводится рабочая версия вашей программы, используя указатели (так называемый "доступ" в Аду). Вам не нужна реализация интерфейса для работы с интерфейсом, как и в примере 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: Я новичок в Аду, я мог бы быть неправильно с вещами, но у меня есть идея от https://github.com/raph-amiard/ada-synth-lib, где это понятие используется много.

Смежные вопросы