www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Assigning Interface to Object

reply Mandeep Singh Brar <mandeep brars.co.in> writes:
Hi,

I am not able to assign an interface to object. The following code
does not compile.

module testObj;

public interface testInterface {
	void someMethod();
}
public class testObj
{
	Object someCaller;
	this(Object caller) {
		someCaller = caller;
	}
	this(testInterface tI, bool xyz) {
		someCaller = tI;
	}
}

Shouldn't this work?

Thanks & Regards
Mandeep
Jan 14 2011
next sibling parent reply Trass3r <un known.com> writes:
 module testObj;

 public interface testInterface {
 	void someMethod();
 }
 public class testObj
 {
 	Object someCaller;
 	this(Object caller) {
 		someCaller = caller;
 	}
 	this(testInterface tI, bool xyz) {
 		someCaller = tI;
 	}
 }

 Shouldn't this work?

Doesn't really make sense. If you cast it to Object you "loose" the interface methods.
Jan 15 2011
next sibling parent Mandeep Singh Brar <mandeep brars.co.in> writes:
But it is for only storage purposes. I can cast it back to the
Interface later when required.

Thanks
Mandeep
Jan 15 2011
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Trass3r <un known.com> wrote:

 module testObj;

 public interface testInterface {
 	void someMethod();
 }
 public class testObj
 {
 	Object someCaller;
 	this(Object caller) {
 		someCaller = caller;
 	}
 	this(testInterface tI, bool xyz) {
 		someCaller = tI;
 	}
 }

 Shouldn't this work?

Doesn't really make sense. If you cast it to Object you "loose" the interface methods.

Same way you lose methods of a subclass when you cast it to a base class. That's allowed, though. -- Simen
Jan 15 2011
prev sibling next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Mandeep Singh Brar <mandeep brars.co.in> wrote:

 Hi,

 I am not able to assign an interface to object. The following code
 does not compile.

 module testObj;

 public interface testInterface {
 	void someMethod();
 }
 public class testObj
 {
 	Object someCaller;
 	this(Object caller) {
 		someCaller = caller;
 	}
 	this(testInterface tI, bool xyz) {
 		someCaller = tI;
 	}
 }

 Shouldn't this work?

Nope. D allows interfaces to be special in certain cases (notably COM, though other may be added in the future), and this precludes making interfaces implicitly castable to Object. -- Simen
Jan 15 2011
next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 15/01/2011 17:44, Steven Schveighoffer wrote:
<snip>
 Which unnecessarily complicates things. For example, you can't compare
 two interfaces (try it!).

?
Jan 15 2011
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Stewart Gordon wrote:
 On 15/01/2011 17:44, Steven Schveighoffer wrote:
 <snip>
 Which unnecessarily complicates things. For example, you can't compare=


 two interfaces (try it!).

?

=2E.. I a =3D ...; I b =3D ...; if (a =3D=3D b) // <-- ERROR --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jan 16 2011
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 16/01/2011 08:23, "Jérôme M. Berger" wrote:
 Stewart Gordon wrote:
 On 15/01/2011 17:44, Steven Schveighoffer wrote:
 <snip>
 Which unnecessarily complicates things. For example, you can't compare
 two interfaces (try it!).

?

... I a = ...; I b = ...; if (a == b) //<-- ERROR

1.065: compiles without error, though it seems to be equivalent to is 2.051: it's really weird ---------- C:\Users\Stewart\Documents\Programming\D\Tests>dmd interface_equals.d interface_equals.d(7): Error: function object.opEquals (Object lhs, Object rhs) is not callable using argument types (I,I) interface_equals.d(7): Error: cannot implicitly convert expression (a) of type i nterface_equals.I to object.Object interface_equals.d(7): Error: cannot implicitly convert expression (b) of type i nterface_equals.I to object.Object ---------- Of course, if the interface declares an opEquals, it's a whole different story.... Stewart.
Jan 16 2011
next sibling parent reply Mandeep Singh Brar <mandeep brars.co.in> writes:
"This would be easily resolved if interfaces were known to be Objects. "

But shouldnt this be the case, because there would be nothing called as an
Interface which can be pointed to; it would be an Object which is implementing
an
interface which is being pointed to. So shouldnt Interfaces be Objects too.
Otherwise, wouldnt it defeat the purpose of having Object as the base class for
everything.

Thanks
Mandeep
Jan 19 2011
next sibling parent Christopher Nicholson-Sauls <ibisbasenji gmail.com> writes:
On 01/20/11 01:01, Mandeep Singh Brar wrote:
 "This would be easily resolved if interfaces were known to be Objects. "
 
 But shouldnt this be the case, because there would be nothing called as an
 Interface which can be pointed to; it would be an Object which is implementing
an
 interface which is being pointed to. So shouldnt Interfaces be Objects too.
 Otherwise, wouldnt it defeat the purpose of having Object as the base class for
 everything.
 
 Thanks
 Mandeep

There are actually Interfaces which don't necessarily imply inheritance from Object. The canonical example being IUnknown and it's own descendants, used for interacting with COM libraries. Another example -- as I understand the implementation at least -- are 'extern(C++)' interfaces, which are really API declarations for C++ classes. That said, these are special cases, and I would expect the assertion that interface <- Object to be true in all other cases. -- Chris N-S
Jan 19 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
 Object is only the base class for all D classes. Interfaces may also
 represent COM objects or C++ classes, which are not subclasses of

Can't the compiler check if it is a normal D interface and then allow (implicit) casts to Object?
Jan 20 2011
prev sibling parent reply Mandeep Singh Brar <mandeep brars.co.in> writes:
Hi,

I was just thinking if implementing interfaces as abstract classes could be a
workaround. Since D anyways allows multiple inheritance, so would it make sense
to just declare interfaces as abstract classes. Would there be any reason not
to do that.

Thanks & Regards
Mandeep
Jan 22 2011
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Mandeep Singh Brar" <mandeep brars.co.in> wrote in message 
news:ihf3gs$2kve$1 digitalmars.com...
 Hi,

 I was just thinking if implementing interfaces as abstract classes could 
 be a workaround. Since D anyways allows multiple inheritance, so would it 
 make sense
 to just declare interfaces as abstract classes. Would there be any reason 
 not to do that.

 Thanks & Regards
 Mandeep

The big one is that D _doesn't_ allow multiple inheritance.
Jan 23 2011
prev sibling parent Mandeep Singh Brar <mandeep brars.co.in> writes:
 interface I {}

 ...

 I a = ...;
 I b = ...;

 if (a == b) //<-- ERROR

"1.065: compiles without error, though it seems to be equivalent to is 2.051: it's really weird " I would guess this should be filed as a bug then. Thanks Mandeep
Jan 19 2011
prev sibling parent Christopher Nicholson-Sauls <ibisbasenji gmail.com> writes:
On 01/15/11 10:34, Simen kjaeraas wrote:
 Mandeep Singh Brar <mandeep brars.co.in> wrote:
 
 Hi,

 I am not able to assign an interface to object. The following code
 does not compile.

 module testObj;

 public interface testInterface {
     void someMethod();
 }
 public class testObj
 {
     Object someCaller;
     this(Object caller) {
         someCaller = caller;
     }
     this(testInterface tI, bool xyz) {
         someCaller = tI;
     }
 }

 Shouldn't this work?

Nope. D allows interfaces to be special in certain cases (notably COM, though other may be added in the future), and this precludes making interfaces implicitly castable to Object.

I believe interfaces marked 'extern(C++)' (for using classes defined by C++) are also somewhat special. Still, one would think that the special cases (IUnknown and extern(C++)) would be enforced without affecting "typical" interfaces. Or is there something about how D's vtbl and other affairs are laid out that I don't know about -- such that casting from an interface to Object would lose something? -- Chris N-S
Jan 15 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 15 Jan 2011 11:34:05 -0500, Simen kjaeraas  
<simen.kjaras gmail.com> wrote:

 Mandeep Singh Brar <mandeep brars.co.in> wrote:

 Hi,

 I am not able to assign an interface to object. The following code
 does not compile.

 module testObj;

 public interface testInterface {
 	void someMethod();
 }
 public class testObj
 {
 	Object someCaller;
 	this(Object caller) {
 		someCaller = caller;
 	}
 	this(testInterface tI, bool xyz) {
 		someCaller = tI;
 	}
 }

 Shouldn't this work?

Nope. D allows interfaces to be special in certain cases (notably COM, though other may be added in the future), and this precludes making interfaces implicitly castable to Object.

Which unnecessarily complicates things. For example, you can't compare two interfaces (try it!). Sorry, had to get my dig in there :P -Steve
Jan 15 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Stewart Gordon <smjg_1998 yahoo.com> wrote:

 Of course, if the interface declares an opEquals, it's a whole different  
 story....

It is? Can't seem to get it to work here, and I get the same errors you get. -- Simen
Jan 16 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 16 Jan 2011 08:11:45 -0500, Stewart Gordon <smjg_1998 yahoo.com>  
wrote:

 On 16/01/2011 08:23, "Jérôme M. Berger" wrote:
 Stewart Gordon wrote:
 On 15/01/2011 17:44, Steven Schveighoffer wrote:
 <snip>
 Which unnecessarily complicates things. For example, you can't compare
 two interfaces (try it!).

?

... I a = ...; I b = ...; if (a == b) //<-- ERROR

1.065: compiles without error, though it seems to be equivalent to is 2.051: it's really weird ---------- C:\Users\Stewart\Documents\Programming\D\Tests>dmd interface_equals.d interface_equals.d(7): Error: function object.opEquals (Object lhs, Object rhs) is not callable using argument types (I,I) interface_equals.d(7): Error: cannot implicitly convert expression (a) of type i nterface_equals.I to object.Object interface_equals.d(7): Error: cannot implicitly convert expression (b) of type i nterface_equals.I to object.Object ---------- Of course, if the interface declares an opEquals, it's a whole different story....

Nope. try it: interface I { bool opEquals(I other); } I a; I b; a == b; // same error. The problem is that when TDPL was implemented, (Object)a == (Object)b was redefined from a.opEquals(b) to object.opEquals(a, b), where object is the module object. That function's signature looks like this: bool opEquals(Object lhs, Object rhs); For some reason the compiler tries to do the same thing with interfaces, but of course, there is no opEquals for your specific interface in object. Even if there was, you'd likely get an overload error. This would be easily resolved if interfaces were known to be Objects. -Steve
Jan 17 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Steven Schveighoffer <schveiguy yahoo.com> wrote:

 Nope.  try it:

 interface I { bool opEquals(I other); }

 I a;
 I b;

 a == b; // same error.

 The problem is that when TDPL was implemented, (Object)a == (Object)b  
 was redefined from a.opEquals(b) to object.opEquals(a, b), where object  
 is the module object.

 That function's signature looks like this:

 bool opEquals(Object lhs, Object rhs);

 For some reason the compiler tries to do the same thing with interfaces,  
 but of course, there is no opEquals for your specific interface in  
 object.  Even if there was, you'd likely get an overload error.

 This would be easily resolved if interfaces were known to be Objects.

There's another way that should work, replacing the global opEquals in object.di with this: equals_t opEquals(T, U)(T lhs, U rhs) if ((is(T == class) || is(T == interface)) && (is(U == class) || is(U == interface))) { if (lhs is rhs) return true; if (lhs is null || rhs is null) return false; static if (__traits(compiles,{lhs.opEquals(rhs);})) { if (typeid(lhs) == typeid(rhs)) return lhs.opEquals(rhs); static if (__traits(compiles,{lhs.opEquals(rhs) && rhs.opEquals(lhs);})) { return lhs.opEquals(rhs) && rhs.opEquals(lhs); } else static assert( false, T.stringof ~ " cannot be compared to a " ~ U.stringof ); } else static assert( false, T.stringof ~ " cannot be compared to a " ~ U.stringof ); } There are some problems, however. This generates bloat, as instantiations are created for each combination of types compared. Also, it is only tested for a few simple cases. -- Simen
Jan 17 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Mandeep Singh Brar <mandeep brars.co.in> wrote:

 "This would be easily resolved if interfaces were known to be Objects. "

 But shouldnt this be the case, because there would be nothing called as  
 an
 Interface which can be pointed to; it would be an Object which is  
 implementing an
 interface which is being pointed to. So shouldnt Interfaces be Objects  
 too.
 Otherwise, wouldnt it defeat the purpose of having Object as the base  
 class for
 everything.

Object is only the base class for all D classes. Interfaces may also represent COM objects or C++ classes, which are not subclasses of Object. -- Simen
Jan 19 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 20 Jan 2011 02:01:26 -0500, Mandeep Singh Brar  
<mandeep brars.co.in> wrote:

 "This would be easily resolved if interfaces were known to be Objects. "

 But shouldnt this be the case, because there would be nothing called as  
 an
 Interface which can be pointed to; it would be an Object which is  
 implementing an
 interface which is being pointed to. So shouldnt Interfaces be Objects  
 too.
 Otherwise, wouldnt it defeat the purpose of having Object as the base  
 class for
 everything.

The issue is COM interfaces. What bugs me about it is, whether an interface derives from IUnknown is known at compile time. I don't think it's possible to define an interface that *doesn't* derive from IUnknown that is not a D Object. I believe the compiler even handles IUnknown interfaces differently. I think the problem is that COM support was added when compile-time functionality was in its infancy. There are quite a few legacy problems due to that. For instance, the builtin array sort routine does not use compile-time information. It would be nice to fix this problem, but I'm not sure how willing Walter is to do it. For sure, we need a solution to the opEquals problem. -Steve
Jan 20 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Speaking of COM.. has anyone successfully used COM interfaces in D2?
I'm asking because a few months ago I gave them a try but I kept
having random access violations. And I *do* mean random, sometimes
adding/removing print statements that don't even touch the state of
the program would cause a crash. I couldn't even transfer the D1 COM
example to D2, even though the D1 example works fine.

I might have to investigate this further soon.
Jan 20 2011
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message 
news:mailman.764.1295584412.4748.digitalmars-d-learn puremagic.com...
 Speaking of COM.. has anyone successfully used COM interfaces in D2?
 I'm asking because a few months ago I gave them a try but I kept
 having random access violations. And I *do* mean random, sometimes
 adding/removing print statements that don't even touch the state of
 the program would cause a crash. I couldn't even transfer the D1 COM
 example to D2, even though the D1 example works fine.

 I might have to investigate this further soon.

Yes, mostly with DirectX. One problem I think I ran into was that I found more then one definiton of IUnknown, and only one made derived interfaces COM interfaces.
Jan 23 2011
prev sibling parent Trass3r <un known.com> writes:
 Speaking of COM.. has anyone successfully used COM interfaces in D2?

I once tried to create a DDraw proxy dll but I can't remember how good it worked. https://bitbucket.org/trass3r/ddrawproxy
Jan 21 2011