www.digitalmars.com         C & C++   DMDScript  

D - Interface Details

reply Luke D <Luke_member pathlink.com> writes:
I was looking at C# a while ago, and was thinking about learning Java.  I
installed the Java SDK and was testing something with interfaces.  I realized
that I wasn't sure if this was possible in Java or D, so I wanted to ask.

In C#, if you have 2 interfaces that have the same method names but are meant to
work in different ways, you can explicitly implement them by doing this:

interface I1
{
int method();
}

interface I2
{
int method();
}

class Dirived : I1, I2
{
int I1.method() // explicit implementation for I1
{
return 1;
}

public int method() // implicit implementation for any other interfaces that
have a method with this name, in this case I2
{
return 2;
}
}

Then you can call ((I1)DirivedInstance).method(); to get I1's implementation and
((I2)DirivedInstance).method() or simply DirivedInstance.method() for I2's
implementation.

Is there any way to achieve this in D?  I'm not sure how this is done in Java,
if it's even possible at all.

By the way, I'm sorry if this has been asked before.
Oct 15 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
I don't know either way. However, the language-independent solution to this
is to use intermediate empty abstract classes to translate the names, as in

interface I1
{
    int method();
}

interface I2
{
    int method();
}

class I1_
    : I1
{
    abstract int I1_method();

    int method()
    {
        return I1_method();
    }
}

class I2_
    : I2
{
    abstract int I2_method();

    int method()
    {
        return I2_method();
    }
}

class Dirived
    : I1_
    , I2_
{
    int I1_method()
    {
        return 1;
    }

    int I2_method()
    {
        return 2;
    }


having explained that, I'd now like to say that it stinks! It'd be great if
D could work out a more elegant way


----- Original Message ----- 
From: "Luke D" <Luke_member pathlink.com>
Newsgroups: D
Sent: Thursday, October 16, 2003 12:13 PM
Subject: Interface Details


 I was looking at C# a while ago, and was thinking about learning Java.  I
 installed the Java SDK and was testing something with interfaces.  I

 that I wasn't sure if this was possible in Java or D, so I wanted to ask.

 In C#, if you have 2 interfaces that have the same method names but are

 work in different ways, you can explicitly implement them by doing this:

 interface I1
 {
 int method();
 }

 interface I2
 {
 int method();
 }

 class Dirived : I1, I2
 {
 int I1.method() // explicit implementation for I1
 {
 return 1;
 }

 public int method() // implicit implementation for any other interfaces

 have a method with this name, in this case I2
 {
 return 2;
 }
 }

 Then you can call ((I1)DirivedInstance).method(); to get I1's

 ((I2)DirivedInstance).method() or simply DirivedInstance.method() for I2's
 implementation.

 Is there any way to achieve this in D?  I'm not sure how this is done in

 if it's even possible at all.

 By the way, I'm sorry if this has been asked before.

Oct 15 2003
parent reply Luke D <Luke_member pathlink.com> writes:
I just tried a few things, and it seems like D is just like Java with this and
doesn't allow multiple implementations (if I'm right in saying that Java
doesn't).  Even C++ allows it (ok, maybe not even, C++ also allows multiple
inheritence, though if something like this could be adopted, even that wouldn't
be as large a problem)  It doesn't allow implicit implementations  with the
explicit though.  Here's the C++ code. I changed the name of the classes when I
wrote the code, too lazy to change them back, and I don't think the old names
make much sense in the context of C++ anyway.

class Parent1
{
public:
virtual int method() = 0;
};

class Parent2
{
public:
virtual int method() = 0;
};

class Dirived : public Parent1, public Parent2
{
public:
int Parent1::method() {return 1;}
int Parent2::method() {return 2;}
};

In article <bml171$1s5g$1 digitaldaemon.com>, Matthew Wilson says...
I don't know either way. However, the language-independent solution to this
is to use intermediate empty abstract classes to translate the names, as in

interface I1
{
    int method();
}

interface I2
{
    int method();
}

class I1_
    : I1
{
    abstract int I1_method();

    int method()
    {
        return I1_method();
    }
}

class I2_
    : I2
{
    abstract int I2_method();

    int method()
    {
        return I2_method();
    }
}

class Dirived
    : I1_
    , I2_
{
    int I1_method()
    {
        return 1;
    }

    int I2_method()
    {
        return 2;
    }


having explained that, I'd now like to say that it stinks! It'd be great if
D could work out a more elegant way


----- Original Message ----- 
From: "Luke D" <Luke_member pathlink.com>
Newsgroups: D
Sent: Thursday, October 16, 2003 12:13 PM
Subject: Interface Details


 I was looking at C# a while ago, and was thinking about learning Java.  I
 installed the Java SDK and was testing something with interfaces.  I

 that I wasn't sure if this was possible in Java or D, so I wanted to ask.

 In C#, if you have 2 interfaces that have the same method names but are

 work in different ways, you can explicitly implement them by doing this:

 interface I1
 {
 int method();
 }

 interface I2
 {
 int method();
 }

 class Dirived : I1, I2
 {
 int I1.method() // explicit implementation for I1
 {
 return 1;
 }

 public int method() // implicit implementation for any other interfaces

 have a method with this name, in this case I2
 {
 return 2;
 }
 }

 Then you can call ((I1)DirivedInstance).method(); to get I1's

 ((I2)DirivedInstance).method() or simply DirivedInstance.method() for I2's
 implementation.

 Is there any way to achieve this in D?  I'm not sure how this is done in

 if it's even possible at all.

 By the way, I'm sorry if this has been asked before.


Oct 15 2003
parent reply Luke D <Luke_member pathlink.com> writes:
Oh, I forgot to mention, by using your suggestion, you break the polymorphism
you'd get with the multiple interfaces.  I'm guessing you're just renaming the
method names because multiple inheritence like that isn't legal in D, and in C++
the only advatage it would provide over the solution I just produced is being
able to call the methods without a cast.

I realize that by allowing multiple implementations like this, the changes that
would have to be made to the compiler and vtable would made them more complex.
However, in the very short look I had at C# and then Java, it was one of the
only things that I found gave the C# programmer a fairly large advantage.

In article <bml6jv$23lu$1 digitaldaemon.com>, Luke D says...
I just tried a few things, and it seems like D is just like Java with this and
doesn't allow multiple implementations (if I'm right in saying that Java
doesn't).  Even C++ allows it (ok, maybe not even, C++ also allows multiple
inheritence, though if something like this could be adopted, even that wouldn't
be as large a problem)  It doesn't allow implicit implementations  with the
explicit though.  Here's the C++ code. I changed the name of the classes when I
wrote the code, too lazy to change them back, and I don't think the old names
make much sense in the context of C++ anyway.

class Parent1
{
public:
virtual int method() = 0;
};

class Parent2
{
public:
virtual int method() = 0;
};

class Dirived : public Parent1, public Parent2
{
public:
int Parent1::method() {return 1;}
int Parent2::method() {return 2;}
};

In article <bml171$1s5g$1 digitaldaemon.com>, Matthew Wilson says...
I don't know either way. However, the language-independent solution to this
is to use intermediate empty abstract classes to translate the names, as in

interface I1
{
    int method();
}

interface I2
{
    int method();
}

class I1_
    : I1
{
    abstract int I1_method();

    int method()
    {
        return I1_method();
    }
}

class I2_
    : I2
{
    abstract int I2_method();

    int method()
    {
        return I2_method();
    }
}

class Dirived
    : I1_
    , I2_
{
    int I1_method()
    {
        return 1;
    }

    int I2_method()
    {
        return 2;
    }


having explained that, I'd now like to say that it stinks! It'd be great if
D could work out a more elegant way


----- Original Message ----- 
From: "Luke D" <Luke_member pathlink.com>
Newsgroups: D
Sent: Thursday, October 16, 2003 12:13 PM
Subject: Interface Details


 I was looking at C# a while ago, and was thinking about learning Java.  I
 installed the Java SDK and was testing something with interfaces.  I

 that I wasn't sure if this was possible in Java or D, so I wanted to ask.

 In C#, if you have 2 interfaces that have the same method names but are

 work in different ways, you can explicitly implement them by doing this:

 interface I1
 {
 int method();
 }

 interface I2
 {
 int method();
 }

 class Dirived : I1, I2
 {
 int I1.method() // explicit implementation for I1
 {
 return 1;
 }

 public int method() // implicit implementation for any other interfaces

 have a method with this name, in this case I2
 {
 return 2;
 }
 }

 Then you can call ((I1)DirivedInstance).method(); to get I1's

 ((I2)DirivedInstance).method() or simply DirivedInstance.method() for I2's
 implementation.

 Is there any way to achieve this in D?  I'm not sure how this is done in

 if it's even possible at all.

 By the way, I'm sorry if this has been asked before.



Oct 16 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Luke D" <Luke_member pathlink.com> wrote in message
news:bmn4c1$1jcq$1 digitaldaemon.com...
 Oh, I forgot to mention, by using your suggestion, you break the

 you'd get with the multiple interfaces.

How so? You can call method() on I1, and it will call I1_method(), and similarly with I2. I never said it was nice - it's damned ugly! - but I don't see how it breaks polymorphism
 I'm guessing you're just renaming the
 method names because multiple inheritence like that isn't legal in D, and

 the only advatage it would provide over the solution I just produced is

 able to call the methods without a cast.

 I realize that by allowing multiple implementations like this, the changes

 would have to be made to the compiler and vtable would made them more

 However, in the very short look I had at C# and then Java, it was one of

 only things that I found gave the C# programmer a fairly large advantage.

 In article <bml6jv$23lu$1 digitaldaemon.com>, Luke D says...
I just tried a few things, and it seems like D is just like Java with


doesn't allow multiple implementations (if I'm right in saying that Java
doesn't).  Even C++ allows it (ok, maybe not even, C++ also allows


inheritence, though if something like this could be adopted, even that


be as large a problem)  It doesn't allow implicit implementations  with


explicit though.  Here's the C++ code. I changed the name of the classes


wrote the code, too lazy to change them back, and I don't think the old


make much sense in the context of C++ anyway.

class Parent1
{
public:
virtual int method() = 0;
};

class Parent2
{
public:
virtual int method() = 0;
};

class Dirived : public Parent1, public Parent2
{
public:
int Parent1::method() {return 1;}
int Parent2::method() {return 2;}
};

In article <bml171$1s5g$1 digitaldaemon.com>, Matthew Wilson says...
I don't know either way. However, the language-independent solution to



is to use intermediate empty abstract classes to translate the names, as



interface I1
{
    int method();
}

interface I2
{
    int method();
}

class I1_
    : I1
{
    abstract int I1_method();

    int method()
    {
        return I1_method();
    }
}

class I2_
    : I2
{
    abstract int I2_method();

    int method()
    {
        return I2_method();
    }
}

class Dirived
    : I1_
    , I2_
{
    int I1_method()
    {
        return 1;
    }

    int I2_method()
    {
        return 2;
    }


having explained that, I'd now like to say that it stinks! It'd be great



D could work out a more elegant way


----- Original Message ----- 
From: "Luke D" <Luke_member pathlink.com>
Newsgroups: D
Sent: Thursday, October 16, 2003 12:13 PM
Subject: Interface Details


 I was looking at C# a while ago, and was thinking about learning Java.




 installed the Java SDK and was testing something with interfaces.  I

 that I wasn't sure if this was possible in Java or D, so I wanted to




 In C#, if you have 2 interfaces that have the same method names but




meant to
 work in different ways, you can explicitly implement them by doing




 interface I1
 {
 int method();
 }

 interface I2
 {
 int method();
 }

 class Dirived : I1, I2
 {
 int I1.method() // explicit implementation for I1
 {
 return 1;
 }

 public int method() // implicit implementation for any other




that
 have a method with this name, in this case I2
 {
 return 2;
 }
 }

 Then you can call ((I1)DirivedInstance).method(); to get I1's

 ((I2)DirivedInstance).method() or simply DirivedInstance.method() for




 implementation.

 Is there any way to achieve this in D?  I'm not sure how this is done




Java,
 if it's even possible at all.

 By the way, I'm sorry if this has been asked before.




Oct 16 2003
parent reply Luke D <Luke_member pathlink.com> writes:
Sorry, what I meant was that your suggestion doesn't work in D and Java because
they don't allow multiple inheritence of classes.  To do something similar,
you'd have to rename the methods, which brakes polymorphism (since you're not
actually implementing the methods in the interface because you're renaming the
methods.  You're just supplying a new method).  In C++ your suggestion's fine,
but it doesn't really add much functionality over C++'s usual way to define
explicit implementation (Child::Parent::Method() {}).

I actually did think of a way to do something similar in Java and D, but it
seems awkward (though powerful) and you'd have to be aware of the possibility of
name conflicts when designing the interfaces and anything that uses the
interfaces.

Here's the D implementation

interface I1
{
void setI1();
int method();
}

interface I2
{
void setI2();
int method();
}

class Dirived : I1, I2
{
public:
this() {Ix_method = &I1_method;}

void setI1() {Ix_method = &I1_method;}
void setI2() {Ix_method = &I2_method;}

int method() {return Ix_method();}

private:
int I1_method() {return 1;}
int I2_method() {return 2;}

int delegate() Ix_method;
}

You'd have to call setI1() or setI2() before calling method() whenever you're
not sure which implementation is being used.  Seems very awkward, and probably
not threadsafe.  Another way it could be done is if the current cast of the
class is passed so that the action could be decided in the method, but this
would probably cause more overhead and worse written code than allowing multiple
implementations.
Again, there might be another way that I'm not aware of because I've not
actually programmed in Java much, and I don't know anyone who has.

In article <bmn519$1kg1$1 digitaldaemon.com>, Matthew Wilson says...
"Luke D" <Luke_member pathlink.com> wrote in message
news:bmn4c1$1jcq$1 digitaldaemon.com...
 Oh, I forgot to mention, by using your suggestion, you break the

 you'd get with the multiple interfaces.

How so? You can call method() on I1, and it will call I1_method(), and similarly with I2. I never said it was nice - it's damned ugly! - but I don't see how it breaks polymorphism
 I'm guessing you're just renaming the
 method names because multiple inheritence like that isn't legal in D, and

 the only advatage it would provide over the solution I just produced is

 able to call the methods without a cast.

 I realize that by allowing multiple implementations like this, the changes

 would have to be made to the compiler and vtable would made them more

 However, in the very short look I had at C# and then Java, it was one of

 only things that I found gave the C# programmer a fairly large advantage.

 In article <bml6jv$23lu$1 digitaldaemon.com>, Luke D says...
I just tried a few things, and it seems like D is just like Java with


doesn't allow multiple implementations (if I'm right in saying that Java
doesn't).  Even C++ allows it (ok, maybe not even, C++ also allows


inheritence, though if something like this could be adopted, even that


be as large a problem)  It doesn't allow implicit implementations  with


explicit though.  Here's the C++ code. I changed the name of the classes


wrote the code, too lazy to change them back, and I don't think the old


make much sense in the context of C++ anyway.

class Parent1
{
public:
virtual int method() = 0;
};

class Parent2
{
public:
virtual int method() = 0;
};

class Dirived : public Parent1, public Parent2
{
public:
int Parent1::method() {return 1;}
int Parent2::method() {return 2;}
};

In article <bml171$1s5g$1 digitaldaemon.com>, Matthew Wilson says...
I don't know either way. However, the language-independent solution to



is to use intermediate empty abstract classes to translate the names, as



interface I1
{
    int method();
}

interface I2
{
    int method();
}

class I1_
    : I1
{
    abstract int I1_method();

    int method()
    {
        return I1_method();
    }
}

class I2_
    : I2
{
    abstract int I2_method();

    int method()
    {
        return I2_method();
    }
}

class Dirived
    : I1_
    , I2_
{
    int I1_method()
    {
        return 1;
    }

    int I2_method()
    {
        return 2;
    }


having explained that, I'd now like to say that it stinks! It'd be great



D could work out a more elegant way


----- Original Message ----- 
From: "Luke D" <Luke_member pathlink.com>
Newsgroups: D
Sent: Thursday, October 16, 2003 12:13 PM
Subject: Interface Details


 I was looking at C# a while ago, and was thinking about learning Java.




 installed the Java SDK and was testing something with interfaces.  I

 that I wasn't sure if this was possible in Java or D, so I wanted to




 In C#, if you have 2 interfaces that have the same method names but




meant to
 work in different ways, you can explicitly implement them by doing




 interface I1
 {
 int method();
 }

 interface I2
 {
 int method();
 }

 class Dirived : I1, I2
 {
 int I1.method() // explicit implementation for I1
 {
 return 1;
 }

 public int method() // implicit implementation for any other




that
 have a method with this name, in this case I2
 {
 return 2;
 }
 }

 Then you can call ((I1)DirivedInstance).method(); to get I1's

 ((I2)DirivedInstance).method() or simply DirivedInstance.method() for




 implementation.

 Is there any way to achieve this in D?  I'm not sure how this is done




Java,
 if it's even possible at all.

 By the way, I'm sorry if this has been asked before.





Oct 16 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Luke D" <Luke_member pathlink.com> wrote in message
news:bmn9g3$1qbj$1 digitaldaemon.com...
 Sorry, what I meant was that your suggestion doesn't work in D and Java

 they don't allow multiple inheritence of classes.  To do something

 you'd have to rename the methods, which brakes polymorphism (since you're

 actually implementing the methods in the interface because you're renaming

 methods.  You're just supplying a new method).  In C++ your suggestion's

 but it doesn't really add much functionality over C++'s usual way to

 explicit implementation (Child::Parent::Method() {}).

Understood. :)
 I actually did think of a way to do something similar in Java and D, but

 seems awkward (though powerful) and you'd have to be aware of the

 name conflicts when designing the interfaces and anything that uses the
 interfaces.

 Here's the D implementation

 interface I1
 {
 void setI1();
 int method();
 }

 interface I2
 {
 void setI2();
 int method();
 }

 class Dirived : I1, I2
 {
 public:
 this() {Ix_method = &I1_method;}

 void setI1() {Ix_method = &I1_method;}
 void setI2() {Ix_method = &I2_method;}

 int method() {return Ix_method();}

 private:
 int I1_method() {return 1;}
 int I2_method() {return 2;}

 int delegate() Ix_method;
 }

 You'd have to call setI1() or setI2() before calling method() whenever

 not sure which implementation is being used.  Seems very awkward, and

 not threadsafe.  Another way it could be done is if the current cast of

 class is passed so that the action could be decided in the method, but

 would probably cause more overhead and worse written code than allowing

 implementations.
 Again, there might be another way that I'm not aware of because I've not
 actually programmed in Java much, and I don't know anyone who has.

Hmm. Dangerous, confusing and inefficient (in both time and space). I'd respectfully suggest this one not be adopted. However, you've raised some fine points, and it's an issue that needs sorting. I confess I'd forgotten that D didn't support MI when I drew up my suggestion. This is one area (of the *very* few) in which MI is very useful, and unless D can think up some mechanism to handle the problem you've highlighted, it's in trouble. Since the only real wart with MI is when having member variables, maybe D should consider having a restricted form of MI that allows methods, but not fields. Walter?
Oct 16 2003
parent Luke D <Luke_member pathlink.com> writes:
In article <bmnapd$1s23$1 digitaldaemon.com>, Matthew Wilson says...
Hmm. Dangerous, confusing and inefficient (in both time and space). I'd
respectfully suggest this one not be adopted.

Right, which is why I'd never use it if I didn't have to.
However, you've raised some fine points, and it's an issue that needs
sorting. I confess I'd forgotten that D didn't support MI when I drew up my
suggestion. This is one area (of the *very* few) in which MI is very useful,
and unless D can think up some mechanism to handle the problem you've
highlighted, it's in trouble.

Since the only real wart with MI is when having member variables, maybe D
should consider having a restricted form of MI that allows methods, but not
fields.

Walter?

I haven't really worked with MI much so I don't know what all of the problems are with it. The only ones that I know of are with name conflicts and virtual methods, both of which are solved by casting to a base class with only 1 implementation. I haven't heard of or encountered any problems with member variables. Could you could you show me an example or direct me to an article on this? I'd apreciate MI in D since I never really understood why it wasn't allowed in Java. However, with the example that I showed, simply allowing multiple implementations would be sufficient. Of course, there are problems that are best solved with MI. For instance, in Java, if you immitate MI by having 2 encapsulated classes and interfacing to both, and they both implement the same interface (sorry if that's hard to understand. I'm not a Java programmer, don't know what it's called) then to switch which class is called by the interface's methods, you need to pull some tricks like the one that I showed before. Also, you can only access protected members and override virtual protected methods with inheritence.
Oct 19 2003