2013-05-04 15 views
5

Không biết mô hình oop này được gọi là gì, nhưng làm thế nào tôi có thể làm cùng một mẫu trong Ada? Ví dụ mã này:Làm cách nào để triển khai giao diện trong 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); 

thất bại của tôi trong Ada: Làm thế nào để sửa chữa nó đúng cách?

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; 

Compiler nói: Builder kết quả cảnh báo: tuyên bố "TestVehicle" là quá muộn kết quả Builder cảnh báo: spec sẽ xuất hiện ngay sau khi tuyên bố "xe"

+0

Tôi không chắc chắn về giao diện, nhưng tôi biết với điều động động, gói cơ sở/gói gốc cần phải nằm trong tệp gói riêng biệt. –

Trả lời

6

Điều quan trọng phải nhận thức được là "Tất cả người dùng định nghĩa các chương trình con nguyên thuỷ của một loại giao diện phải là các chương trình con trừu tượng hoặc các thủ tục rỗng. " (Ref) I.e. bạn không thể định nghĩa một chương trình con có giao diện chính nó như một tham số (vâng, tôi biết điều này khác với Java.) Đây là lý do tại sao bạn nhận được lỗi trên khai báo TestVehicles.

Về cơ bản, bạn phải xác định loại thực hiện (các) giao diện, sau đó làm việc với loại đó.

Chương Ada Rationale trên Interfaces thảo luận về điều này một cách chi tiết. Dưới đây là một ví dụ làm việc dựa trên câu hỏi của bạn - Tôi đã đổi tên một số thứ và sửa một vài lỗi có thể bị mất trong số các thông báo lỗi bạn đang thấy :-) Lưu ý việc thêm một loại 'Concrete_Vehicles' để khởi tạo Giao diện xe.

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; 

Biên dịch và chạy:

[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

giao diện Java-style được giới thiệu vào Ada2005 :

type Vehicle is interface; 

Bất kỳ hoạt động trên giao diện phải trừu tượng:

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

Khi kế thừa giao diện, bạn phải chỉ định giao diện đó và thực hiện các hoạt động được xác định cho giao diện ("ghi đè" cho trình biên dịch biết rằng phải có "bắt đầu" tương ứng. Từ khóa là không bắt buộc, tuy nhiên):

type Tractor is new Vehicle with null record; 

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

Tôi sẽ rời khỏi phần còn lại như một tập thể dục, bạn có thể đọc thêm về giao diện trong wikibook

+0

Đây là những gì tôi đã thử nhưng tôi không biết làm thế nào để làm cho nó hoạt động: – Jossi

+0

Bạn muốn thủ tục TestVehicle để có trong tất cả các loại xe, không chỉ packageVehicle.Vehicle, do đó, thêm 'class: thủ tục TestVehicle (Xe: packageVehicle. Vehicle'class) là – egilhh

+0

Bạn cũng cần hiển thị hàm khởi động mà bạn đang gọi: 'Ada.Text_IO.Put_Line (packageVehicle.Start (Vehicle)); ' hoặc sử dụng ký hiệu chấm chấm (Ada2005): ' Ada. Text_IO.Put_Line (Vehicle.Start); ' Ngoài ra, TestVehicle không trả về một chuỗi, vì vậy bạn sẽ không cần put_lines trong phần chính. – egilhh

0

Dưới đây là một phiên bản làm việc của chương trình của bạn, sử dụng con trỏ (gọi là "truy cập" trong Ada). Bạn không cần thực hiện giao diện để làm việc với giao diện, giống như trong ví dụ Java của bạn, đó là điểm chính của lập trình hướng đối tượng và đa hình.

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: Tôi mới đến Ada, tôi có thể là sai với điều đó, nhưng tôi có ý tưởng từ https://github.com/raph-amiard/ada-synth-lib nơi khái niệm này được sử dụng rất nhiều.