2011-12-11 14 views
18

इसका कारण क्या संकलित नहीं होगा?जब कोई वर्ग एक वंशज इंटरफ़ेस लागू करता है, तो यह स्वचालित रूप से आधार इंटरफ़ेस को लागू करने के रूप में क्यों नहीं गिना जाता है?

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 

इसके विपरीत यह कैसे मैं यह काम कर रहा है:

InterfaceA := ImplementsAB as InterfaceB; 

या

InterfaceA := InterfaceB; 

मेरा मतलब, अगर IInterfaceB IInterfaceA से विरासत और TImplementsAB IInterfaceB लागू करता है, यह नहीं होगा IInterfaceA को लागू करने के लिए तार्किक और संगत प्रकार टाइप करें?

उत्तर

27

ऐसा इसलिए है क्योंकि प्रारंभिक ओएलई/कॉम में एक बग था और बोर्लैंड ने इसके साथ संगत होने का फैसला किया। इस आलेख में इसका उल्लेख है: New Delphi language feature: Multiple inheritance for interfaces in Delphi for .NET। समाधान माइकल ने लिखा है कि वर्ग में स्पष्ट रूप से कक्षा में सभी पूर्वजों के इंटरफेस सूचीबद्ध करना है।

जुड़ा हुआ लेख से कुछ उद्धरण:

समस्या कॉम अपने आप में किया गया था। मॉड्यूल लोड करने के लिए, COM डीएलएल, GetProcAddress को एक प्रसिद्ध प्रविष्टि बिंदु पर लोड करेगा जिसे डीएलएल से निर्यात किया जाना था, डीएलएल फ़ंक्शन को एक अज्ञात इंटरफ़ेस प्राप्त करने के लिए कॉल करें, और उसके बाद आईसीएलएएसफ़ैक्टरी के लिए क्वेरी इंटरफेस। समस्या यह थी कि, जब माइक्रोसॉफ्ट ने आईसीएलएएसएफ़ैक्ट्री 2 के लिए समर्थन जोड़ा, तो उन्होंने आईसीएलएएसफ़ैक्ट्री के लिए पूछे गए मौजूदा कोड के बाद आईसीएलएएसफ़ैक्टरी 2 के लिए क्वेरी इंटरफेस जोड़ा। IClassFactory2 से अनुरोध किया जाएगा यदि IClassFactory के लिए क्वेरी विफल हो गई।

इस प्रकार, COM किसी भी COM सर्वर पर IClassFactory2 का अनुरोध नहीं करेगा जो आईसीएलएएसएफ़ैक्ट्री 2 और आईसीएलएएसफ़ैक्ट्री दोनों को लागू करता है।

यह बग लंबे समय तक COM में मौजूद था। माइक्रोसॉफ्ट ने कहा कि वे ओएस सर्विस पैक के साथ COM लोडर को ठीक नहीं कर सके क्योंकि वर्ड और एक्सेल (उस समय) दोनों ने छोटी गाड़ी व्यवहार पर भरोसा किया था। भले ही यह COM के नवीनतम रिलीज़ में तय किया गया हो या नहीं, बोरलैंड को इस भविष्य को Win32 डेल्फी में भविष्य के लिए सुरक्षित रखने के लिए कुछ तरीका प्रदान करना होगा। अचानक सभी पूर्वजों को एक कार्यान्वयन वर्ग में जोड़ना जो पहले नहीं था, मौजूदा कोड को तोड़ने की संभावना है जो अनजाने में COM लोडर के समान पैटर्न में पड़ता है।

+6

+1 मुझे कारण पता नहीं था, धन्यवाद! मेरे द्वारा –

+1

+1 भी। –

+0

प्रारंभिक ओएलई/COM "बग" क्या है? –

6

इसे काम करने का एक और तरीका कक्षा घोषणा में दोनों इंटरफेस शामिल करना है।

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

मुझे लगता है कि इस संकलक का एहसास करने के लिए है कि TImplementsAB लागू करता IInterfaceA और IInterfaceB दोनों क्या आवश्यक है।

संबंधित मुद्दे