www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - reference to an interface

reply Ryan Steen <Ryan_member pathlink.com> writes:
The documentation on interfaces says, that an instance of an interface cannot be
created. But the examples show how to work with an instance of an interface,
although it is reconverted from a class that derives from it. To understand what
this means I wrote this little peace of code and banged my head against a brick
wall.

interface I{
void help();
}
interface J{
void help();
}
class C1:I{
void help(){
printf( "Hello World.");
}
}
class C2: C1, J{
void help(){
printf( "Hello Grave.");
}
}
void f( I i){
i.help();
}
void main(){
f( new C2);
}

In class C2 I have overridden the function help from class C1 and reimplemented
the function help from interface J, didn't I? Why don't I get the function help
from interface I?

Ryan Steen
--
Ask me again, when I am old enough.
Apr 08 2006
parent reply Frank Benoit <benoit__ __tionex.de> writes:
An interface is something like a promise. A class implementing an
interface promises to have all these methods. Your class C2 is
overriding the method from C1 that's all. Your two "help" methods are
not two different one, they are the same.

C2 promises twice to implement a methods "void help();", inherants the
one from C1 and overrides it.
Apr 08 2006
next sibling parent reply kris <foo bar.com> writes:
Frank Benoit wrote:
 An interface is something like a promise. A class implementing an
 interface promises to have all these methods. Your class C2 is
 overriding the method from C1 that's all. Your two "help" methods are
 not two different one, they are the same.
 
 C2 promises twice to implement a methods "void help();", inherants the
 one from C1 and overrides it.

That's a really good analogy/description ...
Apr 08 2006
parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
kris wrote:
 Frank Benoit wrote:
 An interface is something like a promise. A class implementing an
 interface promises to have all these methods. Your class C2 is
 overriding the method from C1 that's all. Your two "help" methods are
 not two different one, they are the same.

 C2 promises twice to implement a methods "void help();", inherants the
 one from C1 and overrides it.

That's a really good analogy/description ...

Indeed. But when will it promise to sort things too (== when will it really treat instances of an interface as objects) ;) #interface comparable { # int opCmp(Object o); #} # #class item : comparable { # int opCmp(Object o) { return 1; } #} # #void main() { # comparable[] c; // compiler/lang spec "problem" here # c ~= new item; # c ~= new item; # c ~= new item; # # c.sort; // segfaults here #} -- Jari-Matti
Apr 11 2006
parent reply kris <foo bar.com> writes:
Jari-Matti Mškelš wrote:
 kris wrote:
 
Frank Benoit wrote:

An interface is something like a promise. A class implementing an
interface promises to have all these methods. Your class C2 is
overriding the method from C1 that's all. Your two "help" methods are
not two different one, they are the same.

C2 promises twice to implement a methods "void help();", inherants the
one from C1 and overrides it.

That's a really good analogy/description ...

Indeed. But when will it promise to sort things too (== when will it really treat instances of an interface as objects) ;) #interface comparable { # int opCmp(Object o); #} # #class item : comparable { # int opCmp(Object o) { return 1; } #} # #void main() { # comparable[] c; // compiler/lang spec "problem" here # c ~= new item; # c ~= new item; # c ~= new item; # # c.sort; // segfaults here #}

That's an implementation issue. D had a long and sordid history in this regard ~ I used to be one of the primary antagonists, but gave up long ago
Apr 11 2006
parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
kris wrote:
 Jari-Matti Mškelš wrote:
 kris wrote:

 Frank Benoit wrote:

 An interface is something like a promise. A class implementing an
 interface promises to have all these methods. Your class C2 is
 overriding the method from C1 that's all. Your two "help" methods are
 not two different one, they are the same.

 C2 promises twice to implement a methods "void help();", inherants the
 one from C1 and overrides it.

That's a really good analogy/description ...

Indeed. But when will it promise to sort things too (== when will it really treat instances of an interface as objects) ;) #interface comparable { # int opCmp(Object o); #} # #class item : comparable { # int opCmp(Object o) { return 1; } #} # #void main() { # comparable[] c; // compiler/lang spec "problem" here # c ~= new item; # c ~= new item; # c ~= new item; # # c.sort; // segfaults here #}

That's an implementation issue. D had a long and sordid history in this regard ~ I used to be one of the primary antagonists, but gave up long ago

Well, for me it's the only real problem in D. I can live with imports "polluting" namespaces now, but really hope that someday (in the not too distant future) D will correctly support interfaces. Walter already implemented that covariance part of interfaces, so there's much less to implement now (at least Walter admitted that some work needs to be done ;) Hope you still like the other aspects of D since I really appreciate the work you've done with Mango. -- Jari-Matti
Apr 11 2006
parent kris <foo bar.com> writes:
Jari-Matti Mškelš wrote:
 kris wrote:
 
Jari-Matti Mškelš wrote:

kris wrote:


Frank Benoit wrote:


An interface is something like a promise. A class implementing an
interface promises to have all these methods. Your class C2 is
overriding the method from C1 that's all. Your two "help" methods are
not two different one, they are the same.

C2 promises twice to implement a methods "void help();", inherants the
one from C1 and overrides it.

That's a really good analogy/description ...

Indeed. But when will it promise to sort things too (== when will it really treat instances of an interface as objects) ;) #interface comparable { # int opCmp(Object o); #} # #class item : comparable { # int opCmp(Object o) { return 1; } #} # #void main() { # comparable[] c; // compiler/lang spec "problem" here # c ~= new item; # c ~= new item; # c ~= new item; # # c.sort; // segfaults here #}

That's an implementation issue. D had a long and sordid history in this regard ~ I used to be one of the primary antagonists, but gave up long ago

Well, for me it's the only real problem in D. I can live with imports "polluting" namespaces now, but really hope that someday (in the not too distant future) D will correctly support interfaces. Walter already implemented that covariance part of interfaces, so there's much less to implement now (at least Walter admitted that some work needs to be done ;)

 Hope you still like the other aspects of D 

D always held immense promise.
 since I really appreciate the
 work you've done with Mango.

I'm but one part of that project, but thank you, and you're welcome!
Apr 11 2006
prev sibling parent reply Ryan Steen <Ryan_member pathlink.com> writes:
In article <e18ke5$2f95$1 digitaldaemon.com>, Frank Benoit says...
An interface is something like a promise.

But only something? As I understand it now, an interface is a requirement and a promise; it establishes a contract between three parties: client --- serverBoss --- implementer. For those classes inhereting from the interface it is a requirement, i.e. the implementer must fulfill the requirements of his boss. For the instantions of that interface such a class is promising to fulfill the requirement, i.e. the client requests the server to fulfill his promise. But if so, then the interface opens only a view to the class fulfilling the promise. The class itself, which may fulfill also the promises of other interfaces, is of no interest and should be kept private. But if it is private one cannot instantiate it and one needs a function "resolve". But this function cannot be private and therefore is not allowed to belong to the interface. But it is a requirement and should go into an interface .... What I mean is, that when I am a client, then I want to code module client; // I am the client import serverboss; // provides me with the declaration of the interface I import implementer1; // provides me with an implementation of the interface I import implementer2; // ... another implementation of I int main() { serverboss.I i; implementer1.resolve( i); // some code omitted implementer2.resolve( i); // code going on }
Apr 08 2006
parent reply "SÝren J. LÝvborg" <web kwi.dk> writes:
Ryan Steen wrote:
 As I understand it now, an interface is a requirement and a promise; it
 establishes a contract between three parties: client --- serverBoss ---
 implementer.

Not sure what you mean. An interface represents an ability, or functionality. For instance, take the interface std.stream.InputStream, which represent the ability to deliver bytes from an unspecified source. A class implementing an interface promises to provide this functionality. That's only two parties: the implementing class (implementer?) and the program using it (boss?).
 But if so, then the interface opens only a view to the class fulfilling 
 the
 promise. The class itself, which may fulfill also the promises of other
 interfaces, is of no interest and should be kept private.

Yes, you can either make the implementing class public, and allow the user to construct it, or use a factory method that constructs the object for the user, hiding the implementing class.
 But if it is private one cannot instantiate it and one needs a function
 "resolve". But this function cannot be private and therefore is not 
 allowed to
 belong to the interface.

The factory method cannot possibly belong to the interface, since you don't have an instance of the interface until the method returns.
 But it is a requirement and should go into an interface ....

The factory method is not a requirement in the interface, unless the interface represents the ability to produce objects implementing itself. Rather, you need a separate factory class (or interface) which provides the ability to produce objects implementing I.
 What I mean is, that when I am a client, then I want to code

 serverboss.I i;
 implementer1.resolve( i);

Again, not sure what you're trying to do here. -- SÝren J. LÝvborg web kwi.dk
Apr 09 2006
parent reply Ryan Steen <Ryan_member pathlink.com> writes:
In article <e1b1ok$2c5h$1 digitaldaemon.com>, SÝren J. LÝvborg says...
The factory method is not a requirement in the interface, unless the 
interface represents the ability to produce objects implementing itself.

Rather, you need a separate factory class (or interface) which provides the 
ability to produce objects implementing I.

In either case the factory is a member of the _human_ interface to that piece of software. In the second case the factory is by defintion not a member of the _D_ interface. And in the first case it is a member of the _D_ interface but it is unusable because it is not instantiated. So you have confirmed, that currently _human_ interfaces cannot be expressed by _D_ interfaces.
Again, not sure what you're trying to do here.

Please follow another two trys of explanation. First I want you to recall the semantics of the pipe symbol in sh, bash and other shells. A pipe serves as a very simple interface between programs which act as filters. In total the pipe allows you to decompose a complex task into more managable subtasks. 1. Consider the case, that you as the boss of a department have analyzed such a complex task to be decomposable in ten subtasks to which you assign your ten implementers one by one. You want to replace the pipe symbols by adequate D-interfaces, which you define in a separate D-module, but your implementers cannot instantiate them as outlined above. 2. Consider the case that you as before are yourself assigned a subtask of a more complex task. But your boss has left the details of the interfaces to the bosses of the departments. Therefore you have to establish contracts with the bosses of the tasks that are neighbours to your task in form of D-instances. You are facing the same problem as outlined under 1. and in addition you want to encapsulate the implementators of your department by implementing the D-interfaces through wich they must communicate with the world outside of the department. But because the boss of your neighbour task does the same there are now two D-interfaces for that one human interface and there is no way to declare two interfaces as aliases of each other. In total: D-interfaces are not able to mimic human interfaces. So what else can be used to model the cases outlined above?
Apr 10 2006
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Quite actually, as I believe we have return type covariance for interfaces, you
can in 
fact define the factory method in the interface.

# interface IFoo {
#   IFoo make () ;
#
#   bool doSomething () ;
# }

# class MyFoo : IFoo {
#   MyFoo make () { /* stuff */ } // note the return type; a MyFoo 'Is A' IFoo
#
#   protected this () { /* stuff */ }
#
#   bool doSomething () { /* stuff */ }
# }

-- Chris Nicholson-Sauls
Apr 10 2006
parent Ryan Steen <Ryan_member pathlink.com> writes:
In article <e1eeql$e2o$1 digitaldaemon.com>, Chris Nicholson-Sauls says...
Quite actually, as I believe we have return type covariance for interfaces,
you can in fact define the factory method in the interface.

Yes, but the defintion is useless until the class implementing the interface is instantiated. That counters the notion of a factory reachable through the interface. I have to revert to a simple "new", but then I do not need any factory?
Apr 13 2006