www.digitalmars.com         C & C++   DMDScript  

D - Interface Details

reply Luke D <Luke_member pathlink.com> writes:

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.


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



 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.


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 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



 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.


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 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.



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



 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.


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 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
polymorphism
 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
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.

the


 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
 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.

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 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
polymorphism
 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
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.

the


 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
 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.

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 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
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() {}).
Understood. :)
 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.
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