Let me simplify your example: type TNewClass = class(TInterfacedObject,ISecondDescendant);
var First: IFirstDescendant; Second: ISecondDescendant; Second := TNewClass.Create; // Line 1 First := Second; // Line 2 The above compiles and works fine. Line 1 actually performs 2 operations: 1. o := TNewClass.Create, where o is a temp var of type TNewClass 2. Second := o Contrary to popular belief, the second operation does not call QueryInterface. Instead, at compile time, the interface reference is bound to the object reference. This is because at compile time, the interface reference is always a known offset from the object reference (see my last long post). To see this you can either look at the compiled code, or remove the GUID from your interface declaration. Without a GUID, the second operation still works, whereas, if the second operation was: Second := o as ISecondDescendent, without a GUID will raise a compile time error. Line 2 also works because ISecondDescendent implements all methods of IFirstDescendents and are therefore assignment compatible. The important point here is they are assignment compatible, but they are different. However, if you do: First := Second as IFirstDescendent you will get an exception EIntfCastError. This is because the "as" operator calls QueryInterface on Second, and TNewClass does not support IFirstInterface. Regards, Dennis. ----- Original Message ----- From: "Todd Martin" <[EMAIL PROTECTED]> To: "Multiple recipients of list delphi" <[EMAIL PROTECTED]> Sent: Monday, June 16, 2003 1:46 PM Subject: Re: [DUG]: Interface Inheritance > Hi Guys. > > Thanks for all the feedback. I didn't realise it would get so much response. > In the end I decided to go with the following : > IFirstDescendant = interface(IInterface); > ISecondDescendant = interface(IFirstDescendant); > > TNewClass = class(TInterfacedObject,IFirstDescendant ,ISecondDescendant); > > However I noticed one very peculiar aspect of interfaces along the way when > compiling. > > If I define a procedure > DoSomething(AObject : IFirstDescendant); > and > TNewClass = class(TInterfacedObject,ISecondDescendant); > > and then the following code compiles okay > > procedure Test; > var > MyObject : ISecondDescendant; > begin > MyObject := TNewClass.Create; > DoSomething(MyObject); > end; > > I haven't checked yet, but I'm assuming the MyObject passed through to > procedure DoSomething() is then "nil", since TNewClass doesn't support > IFirstDescendant. Would that be your guess too? So why does it compile? On > the otherhand, does the ISecondDescendant pointer get sucessfully converted > to a IFirstDescendant pointer, in which case, why does > MyObject.QueryInterface(IFirstDescendant,FirstObject) return a "nil" pointer > to FirstObject? > > However, if I define > IFirstDescendant = interface(IInterface); > ISecondDescendant = interface(IInterface); > > ie. no interface inheritance - (or whatever you want to call it) > and > > TNewClass = class(TInterfacedObject,IFirstDescendant,ISecondDescendant); > > the Test() procedure does not compile. Any comments? > > Thanks. > > ----- Original Message ----- > From: "Conor Boyd" <[EMAIL PROTECTED]> > To: "Multiple recipients of list delphi" <[EMAIL PROTECTED]> > Sent: Monday, June 16, 2003 10:31 AM > Subject: RE: [DUG]: Interface Inheritance > > > > There are a lot of people (including me) who never use the term 'interface > > inheritance'. You're right, it's not inheritance. > > > > As an aside, having had the 'chance' recently to go some VB6 coding :-( I > > found the Microsoft documentation utterly misleading when it talks about > > interface inheritance, when IMO it should be talking about 'interface > > implementation', which is probably a phrase which is also appropriate to > > what we're talking about here. > > > > Cheers, > > > > Conor > > > > -----Original Message----- > > From: Karl Reynolds [mailto:[EMAIL PROTECTED] > > > > > So this is one simple case where you have IStream inheriting > > > from ISequentialStream (see ActiveX.pas) but you are not required > > > to implement ISequentialStream is you are implementing IStream. > > > > Utterly bizarre. I get your point - that interface "inheritance" has to > be > > implemented the way it is in Delphi in order to support such strangeness. > > But it's not really inheritance any more, is it. > > -------------------------------------------------------------------------- > - > > New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED] > > Website: http://www.delphi.org.nz > > To UnSub, send email to: [EMAIL PROTECTED] > > with body of "unsubscribe delphi" > > Web Archive at: http://www.mail-archive.com/delphi%40delphi.org.nz/ > > > > > -------------------------------------------------------------------------- - > New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED] > Website: http://www.delphi.org.nz > To UnSub, send email to: [EMAIL PROTECTED] > with body of "unsubscribe delphi" > Web Archive at: http://www.mail-archive.com/delphi%40delphi.org.nz/ > --------------------------------------------------------------------------- New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED] Website: http://www.delphi.org.nz To UnSub, send email to: [EMAIL PROTECTED] with body of "unsubscribe delphi" Web Archive at: http://www.mail-archive.com/delphi%40delphi.org.nz/