2013-05-04 22 views
5

Non so come si chiami questo modello oop ma come posso fare lo stesso modello in Ada? Per esempio questo codice:Come implementare l'interfaccia in 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); 

mio tentativo fallito in Ada: Come risolvere in modo corretto?

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; 

compilatore dice: risultati avvertimento Costruttore: dichiarazione di "TestVehicle" è troppo tardi risultati Builder avvertimento: spec dovrebbe apparire immediatamente dopo la dichiarazione di "veicolo"

+0

Non sono sicuro delle interfacce, ma so che con l'invio dinamico il pacchetto base/genitore deve trovarsi in un file di pacchetto separato. –

risposta

6

La cosa fondamentale da considerare è "All definito dall'utente i sottoprogrammi primitivi di un tipo di interfaccia devono essere sottoprogrammi astratti o procedure nulle. " (Ref) I.e. non puoi definire un sottoprogramma che prende come parametro l'interfaccia stessa (sì, lo so che è diverso da Java). Ecco perché stai ricevendo l'errore nella dichiarazione di TestVehicles.

In sostanza, è necessario definire un tipo che implementa l'interfaccia o le interfacce, quindi lavorare con quel tipo.

Il capitolo Razionale di Ada su Interfaces discute questo in dettaglio.

Ecco un esempio funzionante basato sulla tua domanda: ho rinominato alcune cose e corretto un paio di errori che probabilmente si perdevano tra i messaggi di errore che stavi vedendo :-) Nota l'aggiunta di un tipo "Concrete_Vehicles" che istanzia il Interfaccia del veicolo

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; 

compilazione e l'esecuzione:

[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

interfacce in stile Java è stato introdotto nel Ada2005 :

type Vehicle is interface; 

Eventuali operazioni sull'interfaccia devono essere astratto:

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

Quando si eredita l'interfaccia, è necessario specificarla come genitore e implementare le operazioni definite per l'interfaccia ("override" indica al compilatore che il genitore deve avere un "avvio" corrispondente. La parola chiave è facoltativo, tuttavia):

type Tractor is new Vehicle with null record; 

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

Lascerò il resto come un esercizio, si può leggere di più interfacce nel wikibook

+0

Questo è quello che ho provato ma non so come farlo funzionare: – Jossi

+0

Vuoi che la procedura TestVehicle includa tutti i tipi di veicoli, non solo packageVehicle.Vehicle, quindi aggiungi 'class: procedure TestVehicle (Vehicle: packageVehicle. Vehicle'class) è – egilhh

+0

Hai anche bisogno di visibilità per la funzione di avvio che stai chiamando: 'Ada.Text_IO.Put_Line (packageVehicle.Start (Veicolo));' o utilizzare la notazione puntata (Ada2005): 'Ada. Text_IO.Put_Line (Vehicle.Start); ' Inoltre, TestVehicle non restituisce una stringa, quindi non avrai bisogno delle linee_posizioni nel corpo principale. – egilhh

0

Qui di seguito è una versione funzionante del programma, utilizzando i puntatori (chiamato "l'accesso" in Ada). Non hai bisogno di un'implementazione dell'interfaccia per lavorare con l'interfaccia, come nel tuo esempio Java, che è il punto principale della programmazione orientata agli oggetti e del polimorfismo.

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: Sono nuovo di Ada, mi potrebbe essere sbagliato con le cose, ma ho l'idea da https://github.com/raph-amiard/ada-synth-lib in cui questo concetto è molto utilizzato.