digitalmars.D.learn - Default Implementation For an Interface
- Kevin <kevincox.ca gmail.com> Feb 15 2012
- simendsjo <simendsjo gmail.com> Feb 16 2012
- Jacob Carlborg <doob me.com> Feb 16 2012
- Jacob Carlborg <doob me.com> Feb 16 2012
- Jacob Carlborg <doob me.com> Feb 16 2012
- Jacob Carlborg <doob me.com> Feb 16 2012
- Jonathan M Davis <jmdavisProg gmx.com> Feb 16 2012
- "Lukasz" <wrzoski gmail.com> Feb 16 2012
- "Jonathan M Davis" <jmdavisProg gmx.com> Feb 16 2012
- "Jonathan M Davis" <jmdavisProg gmx.com> Feb 16 2012
- "Steven Schveighoffer" <schveiguy yahoo.com> Feb 17 2012
- Jacob Carlborg <doob me.com> Feb 17 2012
- Kevin Cox <kevincox.ca gmail.com> Feb 17 2012
I was implementing a framework and I found that I wanted two things. - A strong set of interfaces so that I can get what I want from a variety of sources. - Some basic implementations of these interfaces. For example, say I was writing a database class. I could either name the interface Database and call the class DatabaseImplementation or something but that is ugly. If I call the interface IDatabase, the Database class looks nice but I need to convince users to write functions that take IDatabases not Databases. I was wondering if there was any way to implement a default implementation. This way, I could create my Database interface and classes could implement that but if you called `new Database()` you would still get a basic database. I thought about doing it in different modules but it just gets messier as you have to fully qualify all of the names so both look ugly. I though about overloading the new operator for the interface but it would have to be final and that would mess everything up. I though about a meathod like `Database.newDefault()` but that is messy and has no meaning in a derived class. I couldn't find anything about this so I was wondering what you would recommend. Should I just pick a naming scheme?
Feb 15 2012
On 02/16/2012 04:01 AM, Kevin wrote:I was implementing a framework and I found that I wanted two things. - A strong set of interfaces so that I can get what I want from a variety of sources. - Some basic implementations of these interfaces. For example, say I was writing a database class. I could either name the interface Database and call the class DatabaseImplementation or something but that is ugly. If I call the interface IDatabase, the Database class looks nice but I need to convince users to write functions that take IDatabases not Databases. I was wondering if there was any way to implement a default implementation. This way, I could create my Database interface and classes could implement that but if you called `new Database()` you would still get a basic database. I thought about doing it in different modules but it just gets messier as you have to fully qualify all of the names so both look ugly. I though about overloading the new operator for the interface but it would have to be final and that would mess everything up. I though about a meathod like `Database.newDefault()` but that is messy and has no meaning in a derived class. I couldn't find anything about this so I was wondering what you would recommend. Should I just pick a naming scheme?
As a user (read developer), I'd rather code to the generic interface when possible. I like that concrete implementations looks rather long and ugly :) I don't think you should be worried that your users is using direct implementations rather than the interface - their problem! Remember that in D, interfaces can contain implementations that only uses static methods on the interface: interface DB { property string name(); // interfaces can have implementations static DB createDefault() { return new GenericDB(); } } class GenericDB : DB { property string name() { return "generic"; } } class MySQLDB : DB { property string name() { return "mysql"; } } void main() { assert(DB.createDefault().name == "generic"); assert((new MySQLDB()).name == "mysql"); }
Feb 16 2012
On 2012-02-16 04:01, Kevin wrote:I was implementing a framework and I found that I wanted two things. - A strong set of interfaces so that I can get what I want from a variety of sources. - Some basic implementations of these interfaces. For example, say I was writing a database class. I could either name the interface Database and call the class DatabaseImplementation or something but that is ugly. If I call the interface IDatabase, the Database class looks nice but I need to convince users to write functions that take IDatabases not Databases. I was wondering if there was any way to implement a default implementation. This way, I could create my Database interface and classes could implement that but if you called `new Database()` you would still get a basic database.
You can create an abstract class that implements some parts of the interface. Then the user (developer) is free to choose to inherit from the interface or the abstract class.I thought about doing it in different modules but it just gets messier as you have to fully qualify all of the names so both look ugly. I though about overloading the new operator for the interface but it would have to be final and that would mess everything up. I though about a meathod like `Database.newDefault()` but that is messy and has no meaning in a derived class. I couldn't find anything about this so I was wondering what you would recommend. Should I just pick a naming scheme?
About the naming scheme I would go for this: interface Database {} abstract AbstractDatabase : Database {} class Implementation : Database {} class Implementation2 : AbstractDatabase {} Possibly suffix the implementations with "Database". class ImplementationDatabase : Database {} class Implementation2Database : AbstractDatabase {} But it feels a bit redundant with "Database" in the implementation name. -- /Jacob Carlborg
Feb 16 2012
On 2012-02-16 11:23, Jonathan M Davis wrote:On Thursday, February 16, 2012 11:11:20 Jacob Carlborg wrote:You can create an abstract class that implements some parts of the interface. Then the user (developer) is free to choose to inherit from the interface or the abstract class.
Which results in a classic problem that you run into in Java all the time when dealing with event-based programming (since it deals with events via interfaces). If you have a class that only really needs to implement a couple of the functions from the interface of an event listener, then you can derive from the class which implements it and gives them all empty bodies. But if you need your class to implement multiple such interfaces, you can only do that with one of them, which gets really annoying, because then you have to create a bunch of empty method bodies yourself. It's one of the classic examples where multiple inheritance would be desirable.
Interfaces and abstract classes is the simple solution. If the class hierarchy is quite simple won't be a problem. It looks like it is quite simple in this case. Or one could skip the interface completely perhaps.The current situation in D is exactly the same (though, since we don't have a swing equivalent, I don't think that it's something that D programmers are frequently running into at the moment). AIUI, Java is going to be adding the ability to give interfaces default implementations such that that implementation is effectively copy-pasted into your class when you implement it and don't provide an implementation yourself (rather than the function in your class overidding it as would be the case with an abstract class). This nicely solves the event listener problem, and D doesn't have that. I assume that that's the sort of thing that the OP is looking for.
Since D have delegates I would use those for event handling and not listeners. I think they are a much better fit, as long as you don't have to force the user to handle many different events on the same object.Now, if you use template mixins, I believe that it's possible to use that to mixin default implementations for the functions in an interface, which should solve the problem for D. So, that's probably good enough for D without having to make it so that interface functions can have default implementations. - Jonathan M Davis
Template mixins cause their own problems. You can't overload methods with template mixins, may it's possible to get around that with aliases, I don't remember. -- /Jacob Carlborg
Feb 16 2012
On 2012-02-16 20:05, Jonathan M Davis wrote:On Thursday, February 16, 2012 13:26:59 Jacob Carlborg wrote:Since D have delegates I would use those for event handling and not listeners. I think they are a much better fit, as long as you don't have to force the user to handle many different events on the same object.
Oh, I'm not necessarily arguing that using interfaces far listeners is the way to go (in fact, I agree that delegates would be much better). It's just that that's a prime example of a situation where you want default implementations for interface methods, since with single inheritance, you can't derive a class from multiple classes which give you default implementations for interface methods.
Ok, I see. I got the impression that you preferred listeners.Now, if you use template mixins, I believe that it's possible to use that to mixin default implementations for the functions in an interface, which should solve the problem for D. So, that's probably good enough for D without having to make it so that interface functions can have default implementations.
Template mixins cause their own problems. You can't overload methods with template mixins, may it's possible to get around that with aliases, I don't remember.
I thought that you could, since they can be virtual, unlike templated functions. I don't know though. It's not something that I've really had to worry about - particularly since so few of my D programs need classes, let alone interfaces (because most of my D programs are small). - Jonathan M Davis
Note that I'm saying "overload" not "override". -- /Jacob Carlborg
Feb 16 2012
On 2012-02-16 22:08, Jonathan M Davis wrote:On Thursday, February 16, 2012 20:17:22 Jacob Carlborg wrote:Note that I'm saying "overload" not "override".
Ah, so you did. Yes, that would probably be a problem, though aliases can probably fix it (that's how you deal with having all of the overloads for a function in the same overload set for a derived class when you only override some of them). But I haven't tried it, so I don't know. - Jonathan M Davis
I know it works with derived classes but I haven't tried it with template mixins. -- /Jacob Carlborg
Feb 16 2012
On Thursday, February 16, 2012 11:11:20 Jacob Carlborg wrote:You can create an abstract class that implements some parts of the interface. Then the user (developer) is free to choose to inherit from the interface or the abstract class.
Which results in a classic problem that you run into in Java all the time when dealing with event-based programming (since it deals with events via interfaces). If you have a class that only really needs to implement a couple of the functions from the interface of an event listener, then you can derive from the class which implements it and gives them all empty bodies. But if you need your class to implement multiple such interfaces, you can only do that with one of them, which gets really annoying, because then you have to create a bunch of empty method bodies yourself. It's one of the classic examples where multiple inheritance would be desirable. The current situation in D is exactly the same (though, since we don't have a swing equivalent, I don't think that it's something that D programmers are frequently running into at the moment). AIUI, Java is going to be adding the ability to give interfaces default implementations such that that implementation is effectively copy-pasted into your class when you implement it and don't provide an implementation yourself (rather than the function in your class overidding it as would be the case with an abstract class). This nicely solves the event listener problem, and D doesn't have that. I assume that that's the sort of thing that the OP is looking for. Now, if you use template mixins, I believe that it's possible to use that to mixin default implementations for the functions in an interface, which should solve the problem for D. So, that's probably good enough for D without having to make it so that interface functions can have default implementations. - Jonathan M Davis
Feb 16 2012
On Thursday, 16 February 2012 at 10:24:44 UTC, Jonathan M Davis wrote:On Thursday, February 16, 2012 11:11:20 Jacob Carlborg wrote:You can create an abstract class that implements some parts of the interface. Then the user (developer) is free to choose to inherit from the interface or the abstract class.
Which results in a classic problem that you run into in Java all the time when dealing with event-based programming (since it deals with events via interfaces). If you have a class that only really needs to implement a couple of the functions from the interface of an event listener, then you can derive from the class which implements it and gives them all empty bodies. But if you need your class to implement multiple such interfaces, you can only do that with one of them, which gets really annoying, because then you have to create a bunch of empty method bodies yourself. It's one of the classic examples where multiple inheritance would be desirable. The current situation in D is exactly the same (though, since we don't have a swing equivalent, I don't think that it's something that D programmers are frequently running into at the moment). AIUI, Java is going to be adding the ability to give interfaces default implementations such that that implementation is effectively copy-pasted into your class when you implement it and don't provide an implementation yourself (rather than the function in your class overidding it as would be the case with an abstract class). This nicely solves the event listener problem, and D doesn't have that. I assume that that's the sort of thing that the OP is looking for. Now, if you use template mixins, I believe that it's possible to use that to mixin default implementations for the functions in an interface, which should solve the problem for D. So, that's probably good enough for D without having to make it so that interface functions can have default implementations. - Jonathan M Davis
BlackHole from std.typeconst can be used for that purpose. import std.typecons; interface A { void a(); int b(void* arg); } interface B { int c(string arg); } interface Common : A, B { } class Good : BlackHole!Common { override int b(void* arg) { return 0; } } void main() { auto g = new Good; g.a(); auto i = g.b(null); auto j = g.c("Hello"); }
Feb 16 2012
On Thursday, February 16, 2012 13:26:59 Jacob Carlborg wrote:Since D have delegates I would use those for event handling and not listeners. I think they are a much better fit, as long as you don't have to force the user to handle many different events on the same object.
Oh, I'm not necessarily arguing that using interfaces far listeners is the way to go (in fact, I agree that delegates would be much better). It's just that that's a prime example of a situation where you want default implementations for interface methods, since with single inheritance, you can't derive a class from multiple classes which give you default implementations for interface methods.Now, if you use template mixins, I believe that it's possible to use that to mixin default implementations for the functions in an interface, which should solve the problem for D. So, that's probably good enough for D without having to make it so that interface functions can have default implementations.
Template mixins cause their own problems. You can't overload methods with template mixins, may it's possible to get around that with aliases, I don't remember.
I thought that you could, since they can be virtual, unlike templated functions. I don't know though. It's not something that I've really had to worry about - particularly since so few of my D programs need classes, let alone interfaces (because most of my D programs are small). - Jonathan M Davis
Feb 16 2012
On Thursday, February 16, 2012 20:17:22 Jacob Carlborg wrote:Note that I'm saying "overload" not "override".
Ah, so you did. Yes, that would probably be a problem, though aliases can probably fix it (that's how you deal with having all of the overloads for a function in the same overload set for a derived class when you only override some of them). But I haven't tried it, so I don't know. - Jonathan M Davis
Feb 16 2012
On Wed, 15 Feb 2012 22:01:51 -0500, Kevin <kevincox.ca gmail.com> wrote:I was implementing a framework and I found that I wanted two things. - A strong set of interfaces so that I can get what I want from a variety of sources. - Some basic implementations of these interfaces. For example, say I was writing a database class. I could either name the interface Database and call the class DatabaseImplementation or something but that is ugly. If I call the interface IDatabase, the Database class looks nice but I need to convince users to write functions that take IDatabases not Databases. I was wondering if there was any way to implement a default implementation. This way, I could create my Database interface and classes could implement that but if you called `new Database()` you would still get a basic database.
Aside from what has been said already, if you wish to have methods that are not static defined in the interface, final methods currently work: interface I { void foo(); final void callFoo() {writeln("about to call foo"); foo(); writeln("ok, I called foo");} } This isn't exactly a "default implementation", since you can't override it. Note that template methods are supposed to work (And also are implicitly final), but this doesn't currently work. http://d.puremagic.com/issues/show_bug.cgi?id=4174 -Steve
Feb 17 2012
On 2012-02-17 18:04, Steven Schveighoffer wrote:On Wed, 15 Feb 2012 22:01:51 -0500, Kevin <kevincox.ca gmail.com> wrote:I was implementing a framework and I found that I wanted two things. - A strong set of interfaces so that I can get what I want from a variety of sources. - Some basic implementations of these interfaces. For example, say I was writing a database class. I could either name the interface Database and call the class DatabaseImplementation or something but that is ugly. If I call the interface IDatabase, the Database class looks nice but I need to convince users to write functions that take IDatabases not Databases. I was wondering if there was any way to implement a default implementation. This way, I could create my Database interface and classes could implement that but if you called `new Database()` you would still get a basic database.
Aside from what has been said already, if you wish to have methods that are not static defined in the interface, final methods currently work: interface I { void foo(); final void callFoo() {writeln("about to call foo"); foo(); writeln("ok, I called foo");} } This isn't exactly a "default implementation", since you can't override it.
But you could have one final method, the implementation and one virtual, the one you would override. It's an idea, I don't know if it's a good one. -- /Jacob Carlborg
Feb 17 2012
--0015175cadb0b8d8db04b92fd4d7 Content-Type: text/plain; charset=UTF-8 I wasn't looking to implement meathods in the interface, I was looking to have a default class that implements the interface that would be created if you called `new Interface();` I don't think this is possible. and now that I think about it I think that it is for a good reason. On Fri, Feb 17, 2012 at 12:21 PM, Jacob Carlborg <doob me.com> wrote:On 2012-02-17 18:04, Steven Schveighoffer wrote:On Wed, 15 Feb 2012 22:01:51 -0500, Kevin <kevincox.ca gmail.com> wrote: I was implementing a framework and I found that I wanted two things.- A strong set of interfaces so that I can get what I want from a variety of sources. - Some basic implementations of these interfaces. For example, say I was writing a database class. I could either name the interface Database and call the class DatabaseImplementation or something but that is ugly. If I call the interface IDatabase, the Database class looks nice but I need to convince users to write functions that take IDatabases not Databases. I was wondering if there was any way to implement a default implementation. This way, I could create my Database interface and classes could implement that but if you called `new Database()` you would still get a basic database.
Aside from what has been said already, if you wish to have methods that are not static defined in the interface, final methods currently work: interface I { void foo(); final void callFoo() {writeln("about to call foo"); foo(); writeln("ok, I called foo");} } This isn't exactly a "default implementation", since you can't override it.
But you could have one final method, the implementation and one virtual, the one you would override. It's an idea, I don't know if it's a good one. -- /Jacob Carlborg
--0015175cadb0b8d8db04b92fd4d7 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I wasn't looking to implement meathods in the interface, I was looking = to have a default class that implements the interface that would be created= if you called `new Interface();` =C2=A0I don't think this is possible.= and now that I think about it I think that it is for a good reason.<br> <br><div class=3D"gmail_quote">On Fri, Feb 17, 2012 at 12:21 PM, Jacob Carl= borg <span dir=3D"ltr"><<a href=3D"mailto:doob me.com">doob me.com</a>&g= t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0= .8ex;border-left:1px #ccc solid;padding-left:1ex"> <div class=3D"im">On 2012-02-17 18:04, Steven Schveighoffer wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Wed, 15 Feb 2012 22:01:51 -0500, Kevin <<a href=3D"mailto:kevincox.ca= gmail.com" target=3D"_blank">kevincox.ca gmail.com</a>> wrote:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I was implementing a framework and I found that I wanted two things.<br> - A strong set of interfaces so that I can get what I want from a<br> variety of sources.<br> - Some basic implementations of these interfaces.<br> <br> For example, say I was writing a database class. I could either name<br> the interface Database and call the class DatabaseImplementation or<br> something but that is ugly. If I call the interface IDatabase, the<br> Database class looks nice but I need to convince users to write<br> functions that take IDatabases not Databases.<br> <br> I was wondering if there was any way to implement a default<br> implementation. This way, I could create my Database interface and<br> classes could implement that but if you called `new Database()` you<br> would still get a basic database.<br> </blockquote> <br> Aside from what has been said already, if you wish to have methods that<br> are not static defined in the interface, final methods currently work:<br> <br> interface I<br> {<br> void foo();<br> final void callFoo() {writeln("about to call foo"); foo(); writel= n("ok,<br> I called foo");}<br> }<br> <br> This isn't exactly a "default implementation", since you can&= #39;t override it.<br> </blockquote> <br></div> But you could have one final method, the implementation and one virtual, th= e one you would override. It's an idea, I don't know if it's a = good one.<span class=3D"HOEnZb"><font color=3D"#888888"><br> <br> <br> -- <br> /Jacob Carlborg<br> </font></span></blockquote></div><br> --0015175cadb0b8d8db04b92fd4d7--
Feb 17 2012









simendsjo <simendsjo gmail.com> 