2011-12-11 29 views
18

Lý do gì sẽ không biên dịch?Khi một lớp thực hiện giao diện con cháu, tại sao nó không tự động được tính là thực hiện giao diện cơ sở?

type 
    IInterfaceA = interface ['{44F93616-0161-4912-9D63-3E8AA140CA0D}'] 
    procedure DoA; 
    end; 

    IInterfaceB = interface(IInterfaceA) ['{80CB6D35-E12F-462A-AAA9-E7C0F6FE0982}'] 
    procedure DoB; 
    end; 

    TImplementsAB = class(TSingletonImplementation, IInterfaceB) 
    procedure DoA; 
    procedure DoB; 
    end; 

var 
    ImplementsAB: TImplementsAB; 
    InterfaceA: IInterfaceA; 
    InterfaceB: IInterfaceB; 
begin 
    ImplementsAB := TImplementsAB.Create; 
    InterfaceA := ImplementsAB; >> incompatible types 
    ... 
end 

Ngược lại đây là cách tôi làm cho nó hoạt:

InterfaceA := ImplementsAB as InterfaceB; 

hoặc

InterfaceA := InterfaceB; 

Ý tôi là, nếu IInterfaceB thừa hưởng từ IInterfaceA và TImplementsAB thực hiện IInterfaceB, nó sẽ không được hợp lý để thực hiện IInterfaceA và kiểu tương thích?

Trả lời

27

Điều này vì OLE/COM sớm có lỗi và Borland đã quyết định tương thích với nó. Điều này được đề cập trong bài viết này: New Delphi language feature: Multiple inheritance for interfaces in Delphi for .NET. Giải pháp là liệt kê tất cả các giao diện tổ tiên một cách rõ ràng trong lớp như Mikael đã viết.

Một số trích dẫn từ các bài viết liên quan:

Vấn đề là trong COM riêng của mình. Để tải một mô-đun, COM sẽ tải DLL, GetProcAddress trên một điểm vào nổi tiếng được cho là được xuất từ ​​tệp DLL, gọi hàm DLL để lấy một giao diện IUnknown và sau đó QueryInterface cho IClassFactory. Vấn đề là, khi Microsoft thêm hỗ trợ cho IClassFactory2, họ đã thêm QueryInterface cho IClassFactory2 sau khi mã hiện có được truy vấn cho IClassFactory. IClassFactory2 sẽ chỉ được yêu cầu nếu truy vấn cho IClassFactory không thành công.

Do đó, COM sẽ không bao giờ yêu cầu IClassFactory2 trên bất kỳ máy chủ COM nào đã triển khai cả IClassFactory2 và IClassFactory.

Lỗi này tồn tại trong COM trong một thời gian dài. Microsoft nói rằng họ không thể sửa chữa bộ tải COM với gói dịch vụ hệ điều hành vì cả Word và Excel (tại thời điểm đó) đều dựa vào hành vi lỗi. Bất kể nó được sửa trong bản phát hành mới nhất của COM hay không, Borland đã cung cấp một số cách để bảo vệ hành vi này trong Win32 Delphi cho tương lai có thể nhìn thấy được. Đột nhiên thêm tất cả các tổ tiên vào một lớp thực hiện mà không có trước đây là rất có khả năng phá vỡ mã hiện tại vô tình rơi vào cùng một khuôn mẫu như bộ nạp COM.

+6

+1 Tôi không biết lý do, cảm ơn! –

+1

+1 từ tôi nữa. –

+0

Lỗi "OLE/COM" sớm nào? –

6

Một cách khác để làm cho nó hoạt động là bao gồm cả hai giao diện trong khai báo lớp.

TImplementsAB = class(TSingletonImplementation, IInterfaceA, IInterfaceB) 
    procedure DoA; 
    procedure DoB; 
end; 

Tôi đoán đây là những gì là cần thiết cho trình biên dịch để nhận ra rằng TImplementsAB thực hiện cả hai IInterfaceAIInterfaceB.

Các vấn đề liên quan