www.digitalmars.com         C & C++   DMDScript  

D - interfaces

reply "Pavel Minayev" <evilone omen.ru> writes:
How do I resolve the conflict of two interfaces in D. I wrote
this:

    interface foo
    {
     void baz();
    }

    interface bar
    {
     void baz()
    }

    class foobar: foo, bar
    {
     void baz() { }
    }

Now foobar is supposed to have two versions of baz() - one from foo,
one from bar. But how do I implement them separately? I can just
write "void baz()", and the compiler doesn't complain (why?!), but
which method actually gets implemented? I tried foo.baz and bar.baz,
but it doesn't work...
Feb 02 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
One more thing. How to crash the compiler? Easy: =)

    class foobar: foobar.foo, foobar.bar
    {
     interface foo
     {
      void baz();
     }

     interface bar
     {
      void baz();
     }

     void baz() { }
    }

I don't see anything wrong in this code. Interfaces declared
inside the class don't differ from those outside, it should
be pretty legal to inherit that class from them... this can
be useful if you want to deal with interfaces but don't want
to expose them to others.

Also, when doing "class foobar: foo, bar", it complains that
"identifier foo is not defined". Why? Shouldn't class know
about all its members?
Feb 02 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a3g9c6$195r$1 digitaldaemon.com...
 One more thing. How to crash the compiler? Easy: =)

     class foobar: foobar.foo, foobar.bar
     {
      interface foo
      {
       void baz();
      }

      interface bar
      {
       void baz();
      }

      void baz() { }
     }

 I don't see anything wrong in this code. Interfaces declared
 inside the class don't differ from those outside, it should
 be pretty legal to inherit that class from them... this can
 be useful if you want to deal with interfaces but don't want
 to expose them to others.

It doesn't work because the compiler's name resolution hasn't parsed the inside of the class when it is trying to resolve the outside.
 Also, when doing "class foobar: foo, bar", it complains that
 "identifier foo is not defined". Why? Shouldn't class know
 about all its members?

Feb 02 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a3gbp0$1got$4 digitaldaemon.com...

 It doesn't work because the compiler's name resolution hasn't parsed the
 inside of the class when it is trying to resolve the outside.

So it should give an error message? 'cause it doesn't...
Feb 02 2002
parent "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a3gfvi$1jia$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a3gbp0$1got$4 digitaldaemon.com...

 It doesn't work because the compiler's name resolution hasn't parsed the
 inside of the class when it is trying to resolve the outside.

So it should give an error message? 'cause it doesn't...

That, then, is a bug!
Feb 02 2002
prev sibling next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
This works:

    interface foobar: foo, bar { }

This crashes the compiler:

    interface foobar: foo, bar;

Not to mention it definitely shoudln't, I think it should be
a legal declaration, useful to "group" methods together or
to declare a separate interface which doesn't differ from
the base one (would be useful for COM event handling).
Feb 02 2002
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a3g93h$1944$1 digitaldaemon.com...
 How do I resolve the conflict of two interfaces in D. I wrote
 this:

     interface foo
     {
      void baz();
     }

     interface bar
     {
      void baz()
     }

     class foobar: foo, bar
     {
      void baz() { }
     }

 Now foobar is supposed to have two versions of baz() - one from foo,
 one from bar. But how do I implement them separately? I can just
 write "void baz()", and the compiler doesn't complain (why?!), but
 which method actually gets implemented? I tried foo.baz and bar.baz,
 but it doesn't work...

What happens is foobar.baz() becomes the baz implementation for BOTH foo and bar.
Feb 02 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a3gbov$1got$3 digitaldaemon.com...

 What happens is foobar.baz() becomes the baz implementation for BOTH foo

 bar.

And if I need to provide separate implementations?...
Feb 02 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a3gfjr$1jb0$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a3gbov$1got$3 digitaldaemon.com...

 What happens is foobar.baz() becomes the baz implementation for BOTH foo

 bar.

And if I need to provide separate implementations?...

Your only option is to change the name on one of the interfaces.
Feb 02 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a3gh3a$1k44$2 digitaldaemon.com...

 Your only option is to change the name on one of the interfaces.

Aren't you going to add some way to resolve this, like in C# or Delphi? Like this: class foobar: foo, bar { void foo.baz() { ... } void bar.baz() { ... } }
Feb 02 2002
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a3gm8e$1m2f$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a3gh3a$1k44$2 digitaldaemon.com...
 Your only option is to change the name on one of the interfaces.

or Delphi? Like this: class foobar: foo, bar { void foo.baz() { ... } void bar.baz() { ... } }

I didn't know those languages offered that. While it's possible to implement that, is it really necessary to support it?
Feb 02 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a3heol$1vvv$1 digitaldaemon.com...

 I didn't know those languages offered that. While it's possible to

 that, is it really necessary to support it?

Yes. Because sometimes it's not you who define the interfaces. It might happen so that two =absolutely= different interfaces, from different vendors, have to be implemented - and they can potentially have name clashes, and you can't just change one of them that simply because it's not your code... so you need a way to different between those methods somehow. So far all languages I've seen provide the interface.method form for this.
Feb 02 2002
next sibling parent reply Paul Apostolik <parabolis softhome.net> writes:
Pavel Minayev wrote:

 "Walter" <walter digitalmars.com> wrote in message
 news:a3heol$1vvv$1 digitaldaemon.com...

 I didn't know those languages offered that. While it's possible to

 that, is it really necessary to support it?

Yes. Because sometimes it's not you who define the interfaces. It might happen so that two =absolutely= different interfaces, from different vendors, have to be implemented - and they can potentially have name clashes, and you can't just change one of them that simply because it's not your code... so you need a way to different between those methods somehow. So far all languages I've seen provide the interface.method form for this.

I believe Java dealt with this same problem with their package naming scheme. -- Paul Apostolik paul arches.uga.edu parabolis softhome.net Command line arguments -- main( int argc, char * * argv ) { if( argc == 1 ) { cout<<"It's a nice day."<<endl; } else { cout<<"Don't argue with me, it _is_ a nice day."<<endl; } }
Feb 03 2002
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
FYI:
As far as I remember, and I've checked in the VM spec, but can't find a real
answer,
in Java if two interfaces declare a function with the same signature (N.B.
Java VM's DO overload on return value, even though the language does not
support this feature)
and you implement BOTH, you only implement one mehtod and calls to that
method from either interface would got to the same method. so  if you have

interface IsRenderable { void draw(); }
interface HasPension { void draw(); }
class A implements IsRenderable, HasPension { void public draw()
 System.out.println("boo!");} }
class B

static void getPension(HasPension h) { h.draw(); }
}
class

static void showObj(IsRenderable r){ r.draw(); }
}
class test
{
       static void main( String[] argv ) {
        A a  = new A();
        B.getPension( a );
        C.showObj( a );
    }
}
well the jdk 1.0.2/1.1 VM did
and it compiles and runs under 1.3 fine.
in java an interface is just "I agree to implement a function with this
signature",nothing more.
and if you try
interface IsRenderable { void draw(); }
interface HasPension { int draw(); }
class A implements IsRenderable, HasPension

  public void draw() { System.out.println("boo!");}
  public int draw() { return 1; }
}
class B

static void getPension(HasPension h) { h.draw(); }
}
class

static void showObj(IsRenderable r) { r.draw(); }
}
class test
{
       static void main( String[] argv ) {
        A a  = new A();
        B.getPension( a );
        System.out.println( "and I get $" + C.showObj( a )+" pension!" );
    }
}
you can't do it unless you write a with in bytecode asm.
you can not do implement an interface that would cause overloading of the
return value

Mike.

"Paul Apostolik" <parabolis softhome.net> wrote in message
news:3C5CF999.868FAF41 softhome.net...
 Pavel Minayev wrote:

 "Walter" <walter digitalmars.com> wrote in message
 news:a3heol$1vvv$1 digitaldaemon.com...

 I didn't know those languages offered that. While it's possible to

 that, is it really necessary to support it?

Yes. Because sometimes it's not you who define the interfaces. It might happen so that two =absolutely= different interfaces, from different vendors, have to be implemented - and they can potentially have name clashes, and you can't just change one of them that simply because it's not your code... so you need a way to different between those methods somehow. So far all languages I've seen provide the interface.method form for this.

I believe Java dealt with this same problem with their package naming scheme. -- Paul Apostolik paul arches.uga.edu parabolis softhome.net Command line arguments -- main( int argc, char * * argv ) { if( argc == 1 ) { cout<<"It's a nice day."<<endl; } else { cout<<"Don't argue with me, it _is_ a nice day."<<endl; } }

Feb 03 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
Yet Delphi and C# do differentiate.
Feb 03 2002
prev sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
When I first looked at what you were talking about, I was with
Walter...why do you need it?  However, I repent.  We do need to be able
to provide separate implementations.

How do we define which of the baz() functions is foobar.baz()?  Or do we
have to call them as foobar.foo.baz() and foobar.bar.baz()???

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Feb 04 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C5ECBF3.3270321C deming-os.org...

 When I first looked at what you were talking about, I was with
 Walter...why do you need it?  However, I repent.  We do need to be able
 to provide separate implementations.

...because matching names doesn't mean matching purposes!
 How do we define which of the baz() functions is foobar.baz()?  Or do we
 have to call them as foobar.foo.baz() and foobar.bar.baz()???

Yes, exactly.
Feb 04 2002
next sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Pavel Minayev wrote:

 How do we define which of the baz() functions is foobar.baz()?  Or do we
 have to call them as foobar.foo.baz() and foobar.bar.baz()???

Yes, exactly.

Exactly what? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 04 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C5F0184.8EFDD824 deming-os.org...
 Pavel Minayev wrote:

 How do we define which of the baz() functions is foobar.baz()?  Or do



 have to call them as foobar.foo.baz() and foobar.bar.baz()???

Yes, exactly.

Exactly what?

Use the qualifier. foobar.foo.baz() or foobar.bar.baz().
Feb 04 2002
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
I can live with that.

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Feb 04 2002
prev sibling parent "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a3mpt3$1gud$1 digitaldaemon.com...
 "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
 news:3C5ECBF3.3270321C deming-os.org...

 When I first looked at what you were talking about, I was with
 Walter...why do you need it?  However, I repent.  We do need to be able
 to provide separate implementations.

...because matching names doesn't mean matching purposes!

I agree, but it can be a drag to. If some interface inherits from another, you can't implement both of these interfaces, except if D does like it does now, assume that when two functions in different interfaces have the same name and signature they represent the same operation. It should be possible to qualify them if you want different behaviour. Possible, but not necessary! -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 04 2002
prev sibling parent Patrick Down <pat codemoon.com> writes:
"Walter" <walter digitalmars.com> wrote in
news:a3heol$1vvv$1 digitaldaemon.com: 

 
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:a3gm8e$1m2f$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a3gh3a$1k44$2 digitaldaemon.com...
 Your only option is to change the name on one of the interfaces.

or Delphi? Like this: class foobar: foo, bar { void foo.baz() { ... } void bar.baz() { ... } }

I didn't know those languages offered that. While it's possible to implement that, is it really necessary to support it?

The way I see it a interface is a contract that says a class implements a certain set of functionality. Just because two functions are named that same between two interfaces does not mean that serve that same purpose in both.
Feb 03 2002
prev sibling parent reply "Carlos Santander B." <carlos8294 msn.com> writes:
"Pavel Minayev" <evilone omen.ru> escribiσ en el mensaje
news:a3gm8e$1m2f$1 digitaldaemon.com...
| "Walter" <walter digitalmars.com> wrote in message
| news:a3gh3a$1k44$2 digitaldaemon.com...
|
| > Your only option is to change the name on one of the interfaces.
|
| Aren't you going to add some way to resolve this, like in C#
| or Delphi? Like this:
|
|     class foobar: foo, bar
|     {
|         void foo.baz() { ... }
|         void bar.baz() { ... }
|     }
|

Some agreed that it could be useful. I'm also for it, specially because this
is illegal:

interface I1 {
 int a();
}
interface I2 {
 void a();
}
class C:I1,I2 {
 void a() { return; }
 int a() { return 0; }
}

But if I could do:

class C:I1,I2 {
 void I2.a() { return; }
 int I1.a() { return 0; }
}

Then there would be no problem. Or am I wrong? I think I am, but I don't why
:D

—————————————————————————
Carlos Santander

|


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17
Mar 23 2003
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
"Carlos Santander B." wrote:

 "Pavel Minayev" <evilone omen.ru> escribi=F3 en el mensaje
 news:a3gm8e$1m2f$1 digitaldaemon.com...
 | "Walter" <walter digitalmars.com> wrote in message
 | news:a3gh3a$1k44$2 digitaldaemon.com...
 |
 | > Your only option is to change the name on one of the interfaces.
 |
 | Aren't you going to add some way to resolve this, like in C#
 | or Delphi? Like this:
 |
 |     class foobar: foo, bar
 |     {
 |         void foo.baz() { ... }
 |         void bar.baz() { ... }
 |     }
 |

 Some agreed that it could be useful. I'm also for it, specially because=

 is illegal:

 interface I1 {
  int a();
 }
 interface I2 {
  void a();
 }
 class C:I1,I2 {
  void a() { return; }
  int a() { return 0; }
 }

 But if I could do:

 class C:I1,I2 {
  void I2.a() { return; }
  int I1.a() { return 0; }
 }

 Then there would be no problem. Or am I wrong? I think I am, but I don'=

 :D

I don't see any reason why the latter version must be illegal. However, = you should note, of course, that you would not be able to call either version= of a() directly, without a cast. -- The Villagers are Online! http://villagersonline.com =2E[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] =2E[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 30 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
That would be the best approach. After all, the usual reason for deriving
from an interface is to deal polymorphically with the instances via the
interface, in which guise the casts are non necessary.

In fact, I can't see how the language could _not_ support this. Is that
really the current state of play? If so, we'll be forced to do use
intermediate classes, a la C++, which really sucks

"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3E86F3FE.43B6C650 deming-os.org...
"Carlos Santander B." wrote:

 "Pavel Minayev" <evilone omen.ru> escribiσ en el mensaje
 news:a3gm8e$1m2f$1 digitaldaemon.com...
 | "Walter" <walter digitalmars.com> wrote in message
 | news:a3gh3a$1k44$2 digitaldaemon.com...
 |
 | > Your only option is to change the name on one of the interfaces.
 |
 | Aren't you going to add some way to resolve this, like in C#
 | or Delphi? Like this:
 |
 |     class foobar: foo, bar
 |     {
 |         void foo.baz() { ... }
 |         void bar.baz() { ... }
 |     }
 |

 Some agreed that it could be useful. I'm also for it, specially because

 is illegal:

 interface I1 {
  int a();
 }
 interface I2 {
  void a();
 }
 class C:I1,I2 {
  void a() { return; }
  int a() { return 0; }
 }

 But if I could do:

 class C:I1,I2 {
  void I2.a() { return; }
  int I1.a() { return 0; }
 }

 Then there would be no problem. Or am I wrong? I think I am, but I don't

 :D

I don't see any reason why the latter version must be illegal. However, you should note, of course, that you would not be able to call either version of a() directly, without a cast. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 30 2003