digitalmars.D - method returning child, doesn't overrides declared method returning parent
-
Mariusz =?UTF-8?B?R2xpd2nFhHNraQ==?=
(10/10)
Aug 29 2011
- Jonathan M Davis (6/17) Aug 29 2011 It's _not_ overriding. It's implementing an interface method. Those are ...
- Mariusz =?UTF-8?B?R2xpd2nFhHNraQ==?= (21/22) Aug 29 2011 Whether it's called overriding or implementing isn't a big deal for me. ...
- Jonathan M Davis (13/38) Aug 29 2011 This seems to compile just fine:
- Mariusz =?UTF-8?B?R2xpd2nFhHNraQ==?= (19/32) Aug 29 2011 I'm sorry - i provided wrong example. I had property in my code, and he
- Jonathan M Davis (25/44) Aug 29 2011 ify by
- Mariusz =?UTF-8?B?R2xpd2nFhHNraQ==?= (5/21) Aug 30 2011 You're absolutely right, it's not symetric. Now i have to think a bit
- Jonathan M Davis (3/24) Aug 30 2011 Just so long as you learn, it's not a waste of my time.
-
Steven Schveighoffer
(23/42)
Aug 30 2011
On Mon, 29 Aug 2011 16:24:46 -0400, Jonathan M Davis
- Jonathan M Davis (33/74) Aug 30 2011 are
-
Steven Schveighoffer
(54/122)
Aug 30 2011
On Tue, 30 Aug 2011 07:04:27 -0400, Jonathan M Davis
- Marco Leise (14/22) Aug 30 2011 This design decision in Java isn't particularly bad I think. Look at how...
- Timon Gehr (16/40) Aug 30 2011 At that point, probably everything breaks, because you cannot inherit
- Andrei Alexandrescu (12/14) Aug 30 2011 That's pretty much it. The entire purpose of the "override" keyword is
- Steven Schveighoffer (21/34) Aug 30 2011 Your (a) and (b) points seem to be pointing to a different conclusion --...
- Andrei Alexandrescu (4/25) Aug 30 2011 No, because the compiler rejects code that doesn't implement all methods...
- travert phare.normalesup.org (Christophe) (3/3) Aug 30 2011 The fact that the code compile only if all interface methods are
- Timon Gehr (7/10) Aug 30 2011 interface I{
- Steven Schveighoffer (4/14) Aug 30 2011 Why not? All a "hook" is is adding an entry into a base class' vtable. ...
- Timon Gehr (2/18) Aug 30 2011 As far as I can tell, a hook is overwriting an existing entry.
- Steven Schveighoffer (4/26) Aug 30 2011 Nothing is "overwritten", what's written into the table is decided at
- Timon Gehr (5/32) Aug 30 2011 It is conceptually "overwritten" at compile time: Copy vtable from
- Steven Schveighoffer (9/45) Aug 30 2011 And that's no different from implementing an interface, or an abstract
- Timon Gehr (3/42) Aug 30 2011 interfaces don't possess an own vtable. It is created from scratch for
- Steven Schveighoffer (12/59) Aug 30 2011 The vtable for the interface is identical in layout for each class
- Timon Gehr (15/75) Aug 30 2011 What I was saying is not that there is no specific layout, just that an
- Steven Schveighoffer (6/19) Aug 30 2011 OK I really can't continue this :) The details we are discussing are
- Timon Gehr (2/23) Aug 30 2011 I guess so. :)
- Daniel Murphy (3/5) Aug 30 2011 At object file generation time generally.
- Andrei Alexandrescu (3/6) Aug 30 2011 It does mean the programmer implemented all methods of the interface.
- Steven Schveighoffer (24/50) Aug 30 2011 When I write code that derives from a base class, I'm declaring with
- Andrei Alexandrescu (4/8) Aug 30 2011 From the cycle "deadpan answers": I think one should use "override"
- Steven Schveighoffer (14/21) Aug 30 2011 Then your description of cases where override helps prevent bugs should ...
- Timon Gehr (5/27) Aug 30 2011 I don't think that you can change a widely used interface into an
- Steven Schveighoffer (28/63) Aug 30 2011 interface I
- Steven Schveighoffer (15/34) Aug 30 2011 That was kind of weird, I guess I should have done:
- Timon Gehr (30/93) Aug 30 2011 I agree.
- Steven Schveighoffer (13/112) Aug 30 2011 I know. What I'm saying is it's feasible for the nature of an interface...
- Timon Gehr (3/8) Aug 30 2011 Chances are that it will detect more errors if "override" actually means...
- Steven Schveighoffer (6/18) Aug 30 2011 Is it just the name? What if it was implement? or override_or_implement...
- Timon Gehr (9/27) Aug 30 2011 I am saying:
- Steven Schveighoffer (7/35) Aug 30 2011 I mean if override was required for reimplementing base class functions ...
- travert phare.normalesup.org (Christophe) (36/36) Aug 30 2011 Personnally, I would like override to be used when implementing
- Jonathan M Davis (13/32) Aug 30 2011 I think that if you wanted full control such that a function is always
- Steven Schveighoffer (13/54) Aug 31 2011 Again, if the intention of your override keyword is to override all base...
- Jonathan M Davis (32/68) Aug 30 2011 If the class doesn't claim that it's implmenting the interface, then it'...
- travert phare.normalesup.org (Christophe) (13/13) Aug 30 2011 I'm not sure what I am talking about (I have never used interfaces so
- Timon Gehr (4/20) Aug 30 2011 +1
<code> interface Interface { Interface method(); } class Class : Interface { override Class method() {} } </code> DMD complains it isn't overriding. How should it be according to specification, and how about making it legal?
Aug 29 2011
On Monday, August 29, 2011 14:09 Mariusz Gliwiński wrote:<code> interface Interface { Interface method(); } class Class : Interface { override Class method() {} } </code> DMD complains it isn't overriding. How should it be according to specification, and how about making it legal?It's _not_ overriding. It's implementing an interface method. Those are two totally different things. And I think that it's horrible that Java considers implementing an interface method as overriding it. I'd _hate_ to see that in D. - Jonathan M Davis
Aug 29 2011
Jonathan M Davis wrote:It's _not_ overriding. It's implementing [...]Whether it's called overriding or implementing isn't a big deal for me. In D we *already* write _override_ keyword to _implement_ method (IMO it's good choice, to match with overriding class methods). But back to the topic, it would be like that: * we have object which implements interface * we have method that returns objects implementing this interface * we want to return object which implements this interface * we can't return it as class (implementation of interface + something more), because we have to be seen ONLY as implementation of this interface result: We have to declare method, that returns child object, then make a proxy to narrow and override interface. So it looks like: <code> Class real_method() {} override Interface method() {stupid_method();} </code> Ps. If someone felt offended by calling "object, that implements interface" a "child object", i'm sorry for that. Thanks, Mariusz Gliwiński
Aug 29 2011
On Monday, August 29, 2011 15:18 Mariusz Gliwiński wrote:Jonathan M Davis wrote:This seems to compile just fine: interface Interface { Interface method(); } class Class : Interface { Class method() {return new Class;} } The problem is the override keyword. _No_ overriding is going on. _That's_ why it's complaining. - Jonathan M DavisIt's _not_ overriding. It's implementing [...]Whether it's called overriding or implementing isn't a big deal for me. In D we *already* write _override_ keyword to _implement_ method (IMO it's good choice, to match with overriding class methods). But back to the topic, it would be like that: * we have object which implements interface * we have method that returns objects implementing this interface * we want to return object which implements this interface * we can't return it as class (implementation of interface + something more), because we have to be seen ONLY as implementation of this interface result: We have to declare method, that returns child object, then make a proxy to narrow and override interface. So it looks like: <code> Class real_method() {} override Interface method() {stupid_method();} </code> Ps. If someone felt offended by calling "object, that implements interface" a "child object", i'm sorry for that.
Aug 29 2011
Jonathan M Davis wrote:This seems to compile just fine: interface Interface { Interface method(); } class Class : Interface { Class method() {return new Class;} } The problem is the override keyword. _No_ overriding is going on. _That's_ why it's complaining.I'm sorry - i provided wrong example. I had property in my code, and he didn't complained about getter, but setter (of course he can't diversify by different return values). <code> interface Interface { void method(Interface); } class Class : Interface { void method(Class) {} } void main() {} </code> So, You're saying it should be possible, and this is DMD bug? So i'll report that. Thanks, Mariusz G.
Aug 29 2011
On Tuesday, August 30, 2011 08:57:53 Mariusz Gliwi=C5=84ski wrote:I'm sorry - i provided wrong example. I had property in my code, and =hedidn't complained about getter, but setter (of course he can't divers=ify bydifferent return values). =20 <code> interface Interface { =09void method(Interface); } class Class : Interface { =09void method(Class) {} } =20 void main() {} </code> =20 So, You're saying it should be possible, and this is DMD bug? So i'll=reportthat.This particular example is not a bug. A function which returns a Class = can be=20 used in exactly the same situations as one which returns an Interface, = because=20 an instance of Class _is_ an instance of Interface. However, an instanc= e of=20 Interface is not necessarily an instance of Class. So, if method takes = an=20 instance of Class, it can't take an instance of Interface unless it's a= lso a=20 Class. So, if you had Interface i =3D funcWhichReturnsInterface(); Class c =3D new Class; i.method(c); //This will compile. c.method(i); //This won't compile. it wouldn't work. Class' implementation of the method function must tak= e=20 _everything_ that Interface's method function can take, and it doesn't = in your=20 example. - Jonathan M Davis
Aug 29 2011
Jonathan M Davis wrote:On Tuesday, August 30, 2011 08:57:53 Mariusz Gliwiński wrote:You're absolutely right, it's not symetric. Now i have to think a bit because i highly relied on this. I'm sorry for taking Your time. Thanks, Mariusz Gliwiński[...] <code> interface Interface { void method(Interface); } class Class : Interface { void method(Class) {} } void main() {} </code>This particular example is not a bug. [...]
Aug 30 2011
On Tuesday, August 30, 2011 12:42:04 Mariusz Gliwi=C5=84ski wrote:Jonathan M Davis wrote:On Tuesday, August 30, 2011 08:57:53 Mariusz Gliwi=C5=84ski wrote:=20 You're absolutely right, it's not symetric. Now i have to think a bit=[...] <code> interface Interface { void method(Interface); } class Class : Interface { void method(Class) {} } =20 void main() {} </code>=20 This particular example is not a bug. [...]because i highly relied on this. I'm sorry for taking Your time.Just so long as you learn, it's not a waste of my time. - Jonathan M Davis
Aug 30 2011
On Mon, 29 Aug 2011 16:24:46 -0400, Jonathan M Davis <jmdavisProg gmx.co= m> = wrote:On Monday, August 29, 2011 14:09 Mariusz Gliwi=C5=84ski wrote:e =<code> interface Interface { Interface method(); } class Class : Interface { override Class method() {} } </code> DMD complains it isn't overriding. How should it be according to specification, and how about making it legal?It's _not_ overriding. It's implementing an interface method. Those ar=two totally different things. And I think that it's horrible that Java =considers implementing an interface method as overriding it. I'd _hate_ to see =that in D.Then this must be a bug? interface I { void foo(); } class C : I { override void foo(); // compiles } I feel override should be *allowed* when implementing interface function= s = (but not required). Otherwise, you get into situations where a base cla= ss = decides to become abstract (doesn't implement a function), but a derived= = class is specifying override (especially if override is required, as is = = planned), if that's a compiler error, I think it's a useless error. -Steve
Aug 30 2011
On Tuesday, August 30, 2011 06:47:03 Steven Schveighoffer wrote:On Mon, 29 Aug 2011 16:24:46 -0400, Jonathan M Davis <jmdavisProg gmx=.com>=20 wrote:areOn Monday, August 29, 2011 14:09 Mariusz Gliwi=C5=84ski wrote:<code> interface Interface { Interface method(); } class Class : Interface { override Class method() {} } </code> =20 DMD complains it isn't overriding. How should it be according to specification, and how about making it legal?=20 It's _not_ overriding. It's implementing an interface method. Those=etwo totally different things. And I think that it's horrible that Java considers implementing an interface method as overriding it. I'd _hate_ to se=ionsthat in D.=20 Then this must be a bug? =20 interface I { void foo(); } =20 class C : I { override void foo(); // compiles } =20 I feel override should be *allowed* when implementing interface funct=(but not required). Otherwise, you get into situations where a base =classdecides to become abstract (doesn't implement a function), but a deri=vedclass is specifying override (especially if override is required, as =isplanned), if that's a compiler error, I think it's a useless error.I think that override belongs on functions which actually override base= class=20 functions. It should be required when a function overrides a base class= =20 function, and it should be disallowed when it's on a function that does= n't=20 override a base class function. Interfaces have nothing to do with it. The whole point of override is to make sure that you know when your fun= ction=20 is or isn't overriding a base class function. Ff the base class changes= , then=20 that's extremely relevant to the derived class, and it _should_ error o= ut if=20 the function is no longer marked as it should be (be it that it has ove= rride=20 when it shouldn't or that it doesn't have it when it should). That way,= you=20 never have functions which override when you didn't mean them to (e.g. = if a=20 new function were added to one of its base classes), and you never have= a=20 function which _doesn't_ override when you mean it to (e.g. when a func= tion=20 was removed from one or more of its base classes). - Jonathan M Davis
Aug 30 2011
On Tue, 30 Aug 2011 07:04:27 -0400, Jonathan M Davis <jmdavisProg gmx.co= m> = wrote:On Tuesday, August 30, 2011 06:47:03 Steven Schveighoffer wrote:On Mon, 29 Aug 2011 16:24:46 -0400, Jonathan M Davis ==<jmdavisProg gmx.com> wrote:On Monday, August 29, 2011 14:09 Mariusz Gliwi=C5=84ski wrote:<code> interface Interface { Interface method(); } class Class : Interface { override Class method() {} } </code> DMD complains it isn't overriding. How should it be according to specification, and how about making it legal?It's _not_ overriding. It's implementing an interface method. Those=earetwo totally different things. And I think that it's horrible that Java considers implementing an interface method as overriding it. I'd _hate_ to se=that in D.Then this must be a bug? interface I { void foo(); } class C : I { override void foo(); // compiles } I feel override should be *allowed* when implementing interface ==functions (but not required). Otherwise, you get into situations where a base =vedclass decides to become abstract (doesn't implement a function), but a deri=isclass is specifying override (especially if override is required, as =e =planned), if that's a compiler error, I think it's a useless error.I think that override belongs on functions which actually override bas=class functions. It should be required when a function overrides a base clas=sfunction, and it should be disallowed when it's on a function that =doesn't override a base class function. Interfaces have nothing to do with it.=The whole point of override is to make sure that you know when your =function is or isn't overriding a base class function. Ff the base class change=s, =then that's extremely relevant to the derived class, and it _should_ error ==out if the function is no longer marked as it should be (be it that it has =override when it shouldn't or that it doesn't have it when it should). That way=, =you never have functions which override when you didn't mean them to (e.g.==if a new function were added to one of its base classes), and you never hav=e afunction which _doesn't_ override when you mean it to (e.g. when a =function was removed from one or more of its base classes).This argument has holes in it: class A { void foo(); } class B : A { version(newlyAddedBFoo) override void foo(); } class C : B { override void foo(); // does not see newly added B.foo } This will compile fine with or without the version enabled. When you sa= y = override, you say "I don't care what came before me, I'm implementing th= is = function." Now, if B decided to make foo final, yeah, you should know = about it. But I don't see why override shouldn't simply work when = overriding a not-yet-implemented function. What about an abstract base method, should override be required? class A { void foo() {} abstract void foo2(); } class B : A { override void foo() {} override void foo2() {} // should override be rejected here? What = utility would an error give you? } At the end of the day, an interface is simply a completely abstract = class. It might even have some implementation via final or template = functions, but it participates in virtual functions much the same way as= = classes do. -Steve
Aug 30 2011
Am 29.08.2011, 22:24 Uhr, schrieb Jonathan M Davis <jmdavisProg gmx.com>:It's _not_ overriding. It's implementing an interface method. Those are two totally different things. And I think that it's horrible that Java considers implementing an interface method as overriding it. I'd _hate_ to see that in D. - Jonathan M DavisThis design decision in Java isn't particularly bad I think. Look at how dim the line is between an interface, an abstract class and a class. Some languages use the notion of a fully abstract class for interfaces. In case you implement one interface and it is somewhat internal you may choose to provide some default implementations and turn it into an abstract class. At this point you should add 'override' to the all descendant classes that override these implementations. If override was mandatory you could easily spot any methods that correspond to something higher in the hierarchy (extended class / interface). What would you argue for when you implement a method of an abstract class for example? Does it override or implement? But D is not Java and there are already cases of implicit interfaces (Range). So it makes sense not to be overly verbose with interfaces in D. - Marco
Aug 30 2011
On 08/30/2011 01:48 PM, Marco Leise wrote:Am 29.08.2011, 22:24 Uhr, schrieb Jonathan M Davis <jmdavisProg gmx.com>:At that point, probably everything breaks, because you cannot inherit from multiple classes.It's _not_ overriding. It's implementing an interface method. Those are two totally different things. And I think that it's horrible that Java considers implementing an interface method as overriding it. I'd _hate_ to see that in D. - Jonathan M DavisThis design decision in Java isn't particularly bad I think. Look at how dim the line is between an interface, an abstract class and a class. Some languages use the notion of a fully abstract class for interfaces. In case you implement one interface and it is somewhat internal you may choose to provide some default implementations and turn it into an abstract class.At this point you should add 'override' to the all descendant classes that override these implementations.If override was mandatory you could easily spot any methods that correspond to something higher in the hierarchy (extended class / interface). What would you argue for when you implement a method of an abstract class for example? Does it override or implement?If there already is an implementation, it overrides it, otherwise it implements it. Easily spotting methods that correspond to something higher in the hierarchy is achieved best with comments. (You actually see to which parent of the class a method belongs.) class C: I{ void somemethod() { } /* interface I */ void someinterfacemethod() { } void someotherinterfacemethod() { } /* class Object */ override string toString() { } }But D is not Java and there are already cases of implicit interfaces (Range). So it makes sense not to be overly verbose with interfaces in D.I agree.
Aug 30 2011
On 08/30/2011 07:13 AM, Timon Gehr wrote:If there already is an implementation, it overrides it, otherwise it implements it.That's pretty much it. The entire purpose of the "override" keyword is to prevent silent bugs of two kinds: (a) User thinks she hooks a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead hooks one. Override helps only in cases where otherwise a silent error would occur. If the compiler issues an error message without the help of override, override is unneeded and illegal. This is the case with interface and abstract methods - "override" is emphatically unneeded because the compiler/linker wouldn't allow the code anyway. Andrei
Aug 30 2011
On Tue, 30 Aug 2011 08:26:17 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 08/30/2011 07:13 AM, Timon Gehr wrote:Your (a) and (b) points seem to be pointing to a different conclusion -- that override should be required for interface methods. Since implementing an interface method does not introduce a new method, it hooks the interface's existing one. I personally think override should be required if it overrides an existing implementation, be rejected if it introduces a completely new symbol, and be optional if it implements an abstract method. The latter rule is purely for code maintenance. 99%, no wait, I think 100% of the time, when a previously abstract base method grows an implementation after you have implemented it in a derived method, the remedy is simply adding override. This feels like annoyance that can be avoided by just putting override on it to begin with. I can't think of a single case where I've implemented a function I *know* is callable by some base class symbol that I'd want to be informed when a base class implements it later on. I don't care, I'm overriding it, no matter what the base class does (unless of course, the base class marks it final, but that would be an error anyways). If the rule must be require or reject, I'd prefer requirement, even for interface methods. -SteveIf there already is an implementation, it overrides it, otherwise it implements it.That's pretty much it. The entire purpose of the "override" keyword is to prevent silent bugs of two kinds: (a) User thinks she hooks a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead hooks one. Override helps only in cases where otherwise a silent error would occur. If the compiler issues an error message without the help of override, override is unneeded and illegal. This is the case with interface and abstract methods - "override" is emphatically unneeded because the compiler/linker wouldn't allow the code anyway.
Aug 30 2011
On 8/30/11 7:45 AM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 08:26:17 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:No, because the compiler rejects code that doesn't implement all methods of an interface. AndreiOn 08/30/2011 07:13 AM, Timon Gehr wrote:Your (a) and (b) points seem to be pointing to a different conclusion -- that override should be required for interface methods.If there already is an implementation, it overrides it, otherwise it implements it.That's pretty much it. The entire purpose of the "override" keyword is to prevent silent bugs of two kinds: (a) User thinks she hooks a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead hooks one. Override helps only in cases where otherwise a silent error would occur. If the compiler issues an error message without the help of override, override is unneeded and illegal. This is the case with interface and abstract methods - "override" is emphatically unneeded because the compiler/linker wouldn't allow the code anyway.
Aug 30 2011
The fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.
Aug 30 2011
On 08/30/2011 05:49 PM, Christophe wrote:The fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On Tue, 30 Aug 2011 12:18:32 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:Nothing is "overwritten", what's written into the table is decided at compile-time. -SteveOn Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On 08/30/2011 06:23 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 12:18:32 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:It is conceptually "overwritten" at compile time: Copy vtable from parent and replace the overriden entries. And I am quite certain that what exactly is in the table is actually decided at link time.On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:Nothing is "overwritten", what's written into the table is decided at compile-time. -SteveOn Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On Tue, 30 Aug 2011 12:55:30 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 06:23 PM, Steven Schveighoffer wrote:And that's no different from implementing an interface, or an abstract class that does not implement an interface completely -- copy the vtable and overwrite the entries.On Tue, 30 Aug 2011 12:18:32 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:It is conceptually "overwritten" at compile time: Copy vtable from parent and replace the overriden entries.On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:Nothing is "overwritten", what's written into the table is decided at compile-time. -SteveOn Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }And I am quite certain that what exactly is in the table is actually decided at link time.The vtable's contents are known at compile time, however, they may not be resolved until link time. But they are not set to one method and then "overwritten" by another at link time, they are filled with symbols known at compile time, and then the symbols are resolved at link time. -Steve
Aug 30 2011
On 08/30/2011 07:06 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 12:55:30 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:interfaces don't possess an own vtable. It is created from scratch for each class implementing the interface.On 08/30/2011 06:23 PM, Steven Schveighoffer wrote:And that's no different from implementing an interface, or an abstract class that does not implement an interface completely -- copy the vtable and overwrite the entries.On Tue, 30 Aug 2011 12:18:32 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:It is conceptually "overwritten" at compile time: Copy vtable from parent and replace the overriden entries.On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:Nothing is "overwritten", what's written into the table is decided at compile-time. -SteveOn Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On Tue, 30 Aug 2011 13:21:09 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 07:06 PM, Steven Schveighoffer wrote:The vtable for the interface is identical in layout for each class implementing it. So if foo() lives at index 0 in the function table for class C, it lives at index 0 for class D as well. Otherwise, polymorphism wouldn't work, and neither would delegates to interfaces. When you call an interface function, the thunk subtracting the offset to get to the class pointer is done by a pre-function code piece, then the real function is jumped to. So yes, each interface has its own vtable layout, similar to how an abstract class with no implementations would have its own vtable, even though it's not instantiable. -SteveOn Tue, 30 Aug 2011 12:55:30 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:interfaces don't possess an own vtable. It is created from scratch for each class implementing the interface.On 08/30/2011 06:23 PM, Steven Schveighoffer wrote:And that's no different from implementing an interface, or an abstract class that does not implement an interface completely -- copy the vtable and overwrite the entries.On Tue, 30 Aug 2011 12:18:32 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:It is conceptually "overwritten" at compile time: Copy vtable from parent and replace the overriden entries.On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:Nothing is "overwritten", what's written into the table is decided at compile-time. -SteveOn Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }
Aug 30 2011
On 08/30/2011 07:29 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 13:21:09 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:What I was saying is not that there is no specific layout, just that an interface by itself does not need to be represented in the object file. All interface vtbls are part of the classinfo of the implementing classes. in interface I{ void method(); } class C: I{ void method(){} } No overriding of an existing implementation is taking place, the interface inheritance creates a new interface vtable.On 08/30/2011 07:06 PM, Steven Schveighoffer wrote:The vtable for the interface is identical in layout for each class implementing it.On Tue, 30 Aug 2011 12:55:30 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:interfaces don't possess an own vtable. It is created from scratch for each class implementing the interface.On 08/30/2011 06:23 PM, Steven Schveighoffer wrote:And that's no different from implementing an interface, or an abstract class that does not implement an interface completely -- copy the vtable and overwrite the entries.On Tue, 30 Aug 2011 12:18:32 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:It is conceptually "overwritten" at compile time: Copy vtable from parent and replace the overriden entries.On 08/30/2011 06:00 PM, Steven Schveighoffer wrote:Nothing is "overwritten", what's written into the table is decided at compile-time. -SteveOn Tue, 30 Aug 2011 11:58:43 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:As far as I can tell, a hook is overwriting an existing entry.On 08/30/2011 05:49 PM, Christophe wrote:Why not? All a "hook" is is adding an entry into a base class' vtable. This is no different, it's just the base "class" is an interface. -SteveThe fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.interface I{ void method(); } class C: I{ void method() {} // not a hook. }So if foo() lives at index 0 in the function table for class C, it lives at index 0 for class D as well. Otherwise, polymorphism wouldn't work, and neither would delegates to interfaces. When you call an interface function, the thunk subtracting the offset to get to the class pointer is done by a pre-function code piece, then the real function is jumped to. So yes, each interface has its own vtable layout, similar to how an abstract class with no implementations would have its own vtable, even though it's not instantiable.Why would an abstract class without implementations need a vtable in the object file?
Aug 30 2011
On Tue, 30 Aug 2011 14:27:25 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:What I was saying is not that there is no specific layout, just that an interface by itself does not need to be represented in the object file. All interface vtbls are part of the classinfo of the implementing classes. in interface I{ void method(); } class C: I{ void method(){} } No overriding of an existing implementation is taking place, the interface inheritance creates a new interface vtable.OK I really can't continue this :) The details we are discussing are abstractly defined in the compiler, and really should have no place in whether something is a 'hook' or not. It really just depends on how you look at it. -Steve
Aug 30 2011
On 08/30/2011 08:32 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 14:27:25 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:I guess so. :)What I was saying is not that there is no specific layout, just that an interface by itself does not need to be represented in the object file. All interface vtbls are part of the classinfo of the implementing classes. in interface I{ void method(); } class C: I{ void method(){} } No overriding of an existing implementation is taking place, the interface inheritance creates a new interface vtable.OK I really can't continue this :) The details we are discussing are abstractly defined in the compiler, and really should have no place in whether something is a 'hook' or not. It really just depends on how you look at it.
Aug 30 2011
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:j3j4m4$2l0u$1 digitalmars.com...And I am quite certain that what exactly is in the table is actually decided at link time.At object file generation time generally.
Aug 30 2011
On 8/30/11 10:49 AM, Christophe wrote:The fact that the code compile only if all interface methods are implemented does not imply that the programmer knows which method he implemented hooks and which does not.It does mean the programmer implemented all methods of the interface. Andrei
Aug 30 2011
On Tue, 30 Aug 2011 11:40:40 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 8/30/11 7:45 AM, Steven Schveighoffer wrote:When I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function. I.e. I think I'm hooking a specific method, and not introducing a new one. If override isn't required, wouldn't the lack of (b) mean you can get a silent bug when altering an interface? For example: interface I { } class C : I { void foo() {} // written expecting that I'm not hooking anything. } Now I is altered to say: interface I { void foo() {} // which is described as doing something completely different than C.foo } -SteveOn Tue, 30 Aug 2011 08:26:17 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:No, because the compiler rejects code that doesn't implement all methods of an interface.On 08/30/2011 07:13 AM, Timon Gehr wrote:Your (a) and (b) points seem to be pointing to a different conclusion -- that override should be required for interface methods.If there already is an implementation, it overrides it, otherwise it implements it.That's pretty much it. The entire purpose of the "override" keyword is to prevent silent bugs of two kinds: (a) User thinks she hooks a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead hooks one. Override helps only in cases where otherwise a silent error would occur. If the compiler issues an error message without the help of override, override is unneeded and illegal. This is the case with interface and abstract methods - "override" is emphatically unneeded because the compiler/linker wouldn't allow the code anyway.
Aug 30 2011
On 8/30/11 11:06 AM, Steven Schveighoffer wrote:When I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override. Andrei
Aug 30 2011
On Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 8/30/11 11:06 AM, Steven Schveighoffer wrote:Then your description of cases where override helps prevent bugs should reflect that: (a) User thinks she overrides a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead overrides one. I consider implementing an interface method to be hooking, since you are hooking calls from said interface. I guess if we want to avoid solving all hooking problems, even those where one does not intend to implement an interface, but accidentally does, or introduce large annoyances where someone changes a widely used interface to an abstract class, then I guess the status quo is good. -SteveWhen I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override.
Aug 30 2011
On 08/30/2011 06:43 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I don't think that you can change a widely used interface into an abstract class and not introduce annoyances much larger than override is capable of creating. How does the status quo prevent implementing interface methods by accident?On 8/30/11 11:06 AM, Steven Schveighoffer wrote:Then your description of cases where override helps prevent bugs should reflect that: (a) User thinks she overrides a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead overrides one. I consider implementing an interface method to be hooking, since you are hooking calls from said interface. I guess if we want to avoid solving all hooking problems, even those where one does not intend to implement an interface, but accidentally does, or introduce large annoyances where someone changes a widely used interface to an abstract class, then I guess the status quo is good. -SteveWhen I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override.
Aug 30 2011
On Tue, 30 Aug 2011 13:06:02 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 06:43 PM, Steven Schveighoffer wrote:interface I { int foo(); void bar(); } -> interface _I { int foo(); void bar(); } abstract class I : _I { int foo() { return 0; } } Now, everywhere I was implemented before has to change all their implementations of foo() to override, just to compile. There may be some cases where classes already had a base class, but it depends on the context of where I is implemented. However, in 100% of the cases, putting override on each implementation of foo does *not* result in a bug. My point is, what "bug" is it preventing by rejecting override when implementing an interface? The only "bug" I see is that you didn't put override in the signature. That translates to an annoyance, not a real bug.On Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I don't think that you can change a widely used interface into an abstract class and not introduce annoyances much larger than override is capable of creating.On 8/30/11 11:06 AM, Steven Schveighoffer wrote:Then your description of cases where override helps prevent bugs should reflect that: (a) User thinks she overrides a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead overrides one. I consider implementing an interface method to be hooking, since you are hooking calls from said interface. I guess if we want to avoid solving all hooking problems, even those where one does not intend to implement an interface, but accidentally does, or introduce large annoyances where someone changes a widely used interface to an abstract class, then I guess the status quo is good. -SteveWhen I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override.How does the status quo prevent implementing interface methods by accident?It doesn't. That was my point. -Steve
Aug 30 2011
On Tue, 30 Aug 2011 13:16:58 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Tue, 30 Aug 2011 13:06:02 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:That was kind of weird, I guess I should have done: interface I { int foo(); void bar(); } -> abstract class I { int foo() { return 0; } void bar(); } -SteveI don't think that you can change a widely used interface into an abstract class and not introduce annoyances much larger than override is capable of creating.interface I { int foo(); void bar(); } -> interface _I { int foo(); void bar(); } abstract class I : _I { int foo() { return 0; } }
Aug 30 2011
On 08/30/2011 07:16 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 13:06:02 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:That is what I meant.On 08/30/2011 06:43 PM, Steven Schveighoffer wrote:interface I { int foo(); void bar(); } -> interface _I { int foo(); void bar(); } abstract class I : _I { int foo() { return 0; } } Now, everywhere I was implemented before has to change all their implementations of foo() to override, just to compile. There may be some cases where classes already had a base class, but it depends on the context of where I is implemented.On Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I don't think that you can change a widely used interface into an abstract class and not introduce annoyances much larger than override is capable of creating.On 8/30/11 11:06 AM, Steven Schveighoffer wrote:Then your description of cases where override helps prevent bugs should reflect that: (a) User thinks she overrides a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead overrides one. I consider implementing an interface method to be hooking, since you are hooking calls from said interface. I guess if we want to avoid solving all hooking problems, even those where one does not intend to implement an interface, but accidentally does, or introduce large annoyances where someone changes a widely used interface to an abstract class, then I guess the status quo is good. -SteveWhen I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override.However, in 100% of the cases, putting override on each implementation of foo does *not* result in a bug.I agree.My point is, what "bug" is it preventing by rejecting override when implementing an interface? The only "bug" I see is that you didn't put override in the signature. That translates to an annoyance, not a real bug.This one: interface I{ void method1(); void method2(); void method3(); } class C: I{ override void method1(){ ... } override void method2(){ ... } override void method3(){ ... } } => // refactoring implementations of I in C to abstract class D interface I{ void method1(); void method2(); void method3(); } abstract class D: I{ override void method1(){ ... } override void method2(){ ... } override void method3(){ ... } } class C: D{ // left method2() inside class C by accident override void method2(){ ... } // override makes compiler shut up }Oh, I am sorry. I misread your sentence.How does the status quo prevent implementing interface methods by accident?It doesn't. That was my point.
Aug 30 2011
On Tue, 30 Aug 2011 13:39:35 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 07:16 PM, Steven Schveighoffer wrote:I know. What I'm saying is it's feasible for the nature of an interface to be such that you don't have inheritance chains of more than one class. Typically a change like this is done for entire libraries where one person is in control of all the implementing classes, and the author knows the interface to abstract class change will not be a burden. Technically, the problems created would make such a change not feasible, not just annoying. I'm talking about cases where it is feasible.On Tue, 30 Aug 2011 13:06:02 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:That is what I meant.On 08/30/2011 06:43 PM, Steven Schveighoffer wrote:interface I { int foo(); void bar(); } -> interface _I { int foo(); void bar(); } abstract class I : _I { int foo() { return 0; } } Now, everywhere I was implemented before has to change all their implementations of foo() to override, just to compile. There may be some cases where classes already had a base class, but it depends on the context of where I is implemented.On Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I don't think that you can change a widely used interface into an abstract class and not introduce annoyances much larger than override is capable of creating.On 8/30/11 11:06 AM, Steven Schveighoffer wrote:Then your description of cases where override helps prevent bugs should reflect that: (a) User thinks she overrides a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead overrides one. I consider implementing an interface method to be hooking, since you are hooking calls from said interface. I guess if we want to avoid solving all hooking problems, even those where one does not intend to implement an interface, but accidentally does, or introduce large annoyances where someone changes a widely used interface to an abstract class, then I guess the status quo is good. -SteveWhen I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override.We could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot be perfect in detecting refactoring errors. -SteveMy point is, what "bug" is it preventing by rejecting override when implementing an interface? The only "bug" I see is that you didn't put override in the signature. That translates to an annoyance, not a real bug.This one: interface I{ void method1(); void method2(); void method3(); } class C: I{ override void method1(){ ... } override void method2(){ ... } override void method3(){ ... } } => // refactoring implementations of I in C to abstract class D interface I{ void method1(); void method2(); void method3(); } abstract class D: I{ override void method1(){ ... } override void method2(){ ... } override void method3(){ ... } } class C: D{ // left method2() inside class C by accident override void method2(){ ... } // override makes compiler shut up }
Aug 30 2011
On 08/30/2011 07:50 PM, Steven Schveighoffer wrote:We could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot be perfect in detecting refactoring errors. -SteveChances are that it will detect more errors if "override" actually means override.
Aug 30 2011
On Tue, 30 Aug 2011 14:30:42 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 07:50 PM, Steven Schveighoffer wrote:Is it just the name? What if it was implement? or override_or_implement? Would that make it "detect more errors"? I can't see how finding more bugs is a bad thing, regardless of what the name of the keyword is. -SteveWe could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot be perfect in detecting refactoring errors. -SteveChances are that it will detect more errors if "override" actually means override.
Aug 30 2011
On 08/30/2011 08:35 PM, Steven Schveighoffer wrote:On Tue, 30 Aug 2011 14:30:42 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:I am saying: override_or_implement naturally will detect less errors because it is less specific. Based on context it either means "do nothing special" or "override that method". (that is the current behavior of "override" of course) Renaming the keyword would make its current meaning more explicit, it wouldn't make it detect more errors.On 08/30/2011 07:50 PM, Steven Schveighoffer wrote:Is it just the name? What if it was implement? or override_or_implement? Would that make it "detect more errors"?We could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot be perfect in detecting refactoring errors. -SteveChances are that it will detect more errors if "override" actually means override.I can't see how finding more bugs is a bad thing, regardless of what the name of the keyword is.Therefore we agree?
Aug 30 2011
On Tue, 30 Aug 2011 14:56:46 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 08/30/2011 08:35 PM, Steven Schveighoffer wrote:I mean if override was required for reimplementing base class functions and required for implementing interface functions. The errors it doesn't detect is when an interface changes to a class, and for some reason you no longer want to override, um... I have no idea what errors it wouldn't detect. -SteveOn Tue, 30 Aug 2011 14:30:42 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:I am saying: override_or_implement naturally will detect less errors because it is less specific. Based on context it either means "do nothing special" or "override that method". (that is the current behavior of "override" of course) Renaming the keyword would make its current meaning more explicit, it wouldn't make it detect more errors.On 08/30/2011 07:50 PM, Steven Schveighoffer wrote:Is it just the name? What if it was implement? or override_or_implement? Would that make it "detect more errors"?We could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot be perfect in detecting refactoring errors. -SteveChances are that it will detect more errors if "override" actually means override.
Aug 30 2011
Personnally, I would like override to be used when implementing interfaces too, because there is really some hooking happening (and thus hijacking risks), regardless of the presence of a previous method or not. If the problem is that you may have a method witch overrides an abstract class C when the overide keyword was meant for an interface before restructuring, well, that can happen. Let's take your example: interface I { void foo(); } class C:I { override void foo(); } -> becomes -> interface I { void foo(); } class B:I { override void foo(); } class C:B { override void foo(); } // left by mistake Maybe foo was left by mistake, but from the beginning (before creating class B), the method was meant to override I, so it must not be that bad. Moreover, the override keyword is present, so you should be careful when looking at class C. This seems to me to be less important that implementing an interface by mistake (apparently not to everybody). Anyway this could happen anyway if 'I' was an abstract class at the beginning. If you are concerned by knowing exactly what you override (ant it's a good thing) when you use the override keyword, the langage should help you with an argument to the override attribute: interface I { void foo(); } class B:I { override(I) void foo(); } class C:B { override(I) void foo(); } // left by mistake ^ error: foo() is overriding B.foo() abstract class B2:I { } class C2:B2 { override(I) void foo(); } // would works fine class C3:B2 { override(B) void foo(); } ^ error: foo() is overriding I.foo() The argument to override should be optionnal, so that every good code will not be broken. Cheers. -- Christophe Travert
Aug 30 2011
On Tuesday, August 30, 2011 11:35 Steven Schveighoffer wrote:On Tue, 30 Aug 2011 14:30:42 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:I think that if you wanted full control such that a function is always overriding when you want it and never when you don't want it to and such that it's always implementing when you want it to and never when you don't want it to, then we're going to need to add implements (or more likely, implements) on top of override. The two concepts are similar but separate, and overloading override to do both just creates a separate set of problems (e.g. you thought that a function was overriding a base class function and implementing an interface and now it's just implementing an interface, so you don't catch the fact that the base class function is gone unless you were explictly calling it in the derived function). So, if we were to make a change, I'd argue for adding implements rather than altering how override works. - Jonathan M DavisOn 08/30/2011 07:50 PM, Steven Schveighoffer wrote:Is it just the name? What if it was implement? or override_or_implement? Would that make it "detect more errors"? I can't see how finding more bugs is a bad thing, regardless of what the name of the keyword is.We could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot be perfect in detecting refactoring errors. -SteveChances are that it will detect more errors if "override" actually means override.
Aug 30 2011
On Tue, 30 Aug 2011 17:41:46 -0400, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Tuesday, August 30, 2011 11:35 Steven Schveighoffer wrote:Again, if the intention of your override keyword is to override all base class/interface functionality, who cares what changes underneath? As long as the hook is still present, there is no error when the base class disappears. I see zero value for separating implements from override. The main purpose of override is to say "I expect that some base class (or interface) declares this function, and I want to write an implementation for it". I agree that override for interfaces is not necessary in some cases (for example, if you write the incorrect signature, it's an error anyway), but there are some cases where it helps. I don't see what the *harm* is in using it, it's already there. -SteveOn Tue, 30 Aug 2011 14:30:42 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:I think that if you wanted full control such that a function is always overriding when you want it and never when you don't want it to and such that it's always implementing when you want it to and never when you don't want it to, then we're going to need to add implements (or more likely, implements) on top of override. The two concepts are similar but separate, and overloading override to do both just creates a separate set of problems (e.g. you thought that a function was overriding a base class function and implementing an interface and now it's just implementing an interface, so you don't catch the fact that the base class function is gone unless you were explictly calling it in the derived function). So, if we were to make a change, I'd argue for adding implements rather than altering how override works.On 08/30/2011 07:50 PM, Steven Schveighoffer wrote:perfectWe could find cases like this all day. Make I a class, and this problem also occurs. Without the compiler having access to the *changes* it cannot bemeansin detecting refactoring errors. -SteveChances are that it will detect more errors if "override" actuallyoverride.Is it just the name? What if it was implement? or override_or_implement? Would that make it "detect more errors"? I can't see how finding more bugs is a bad thing, regardless of what the name of the keyword is.
Aug 31 2011
On Tuesday, August 30, 2011 10:06 Timon Gehr wrote:On 08/30/2011 06:43 PM, Steven Schveighoffer wrote:If the class doesn't claim that it's implmenting the interface, then it's a non-issue. You have to declare it to be implementing the interface (or one of its base classes must be declared to implement it) for it to be usable as that interface. If you declare a base class to implement an interface, then that base class must either delare or implement all of the functions in the interface. Any function which a derived class might implement is going to need override (assuming that you compile with -w), since it would be overriding the base class' function. If you declare a derived class to implement an interface, then that class must declare or implement all of the functions in the interface. Any function in a base class which happens to match an interface function won't count towards implementing the interface (not even with alias apparently - I don't know if that's a bug or not). So, it would have to be declared in the derived class, and (assuming that you compile with -w) override would catch the fact that a base class happened to implement the same function. But even without override, you can't use the base class as the interface anyway, so the fact that the derived class must declare or implement all of the interface's functions itself means that a base class implementation won't accidentally count as implementing an interface function. The _only_ case where you can accidentally implement an interface function is if you have a function in the class which is supposed to be implementing the interface which happens to implement an interface function, and you didn't notice - that is, you declared the function previously, added the fact that the class implements an interface, forgot to make the class properly implement one of the interface's functions, the existing function matches the interface function that you missed, and you don't notice. That's not a particularly likely scenario unless you have ridiculously large class or are doing something with mixins. So, "accidentally" implementing an interface function isn't really an issue. - Jonathan M DavisOn Tue, 30 Aug 2011 12:29:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I don't think that you can change a widely used interface into an abstract class and not introduce annoyances much larger than override is capable of creating. How does the status quo prevent implementing interface methods by accident?On 8/30/11 11:06 AM, Steven Schveighoffer wrote:Then your description of cases where override helps prevent bugs should reflect that: (a) User thinks she overrides a specific method but instead introduces a new one. (b) User thinks she introduces a new method but instead overrides one. I consider implementing an interface method to be hooking, since you are hooking calls from said interface. I guess if we want to avoid solving all hooking problems, even those where one does not intend to implement an interface, but accidentally does, or introduce large annoyances where someone changes a widely used interface to an abstract class, then I guess the status quo is good. -SteveWhen I write code that derives from a base class, I'm declaring with override that I want to implement the base class' function. When I write code that implements an interface, I'm declaring with override that I want to implement the interface's function.From the cycle "deadpan answers": I think one should use "override" when one wants to override.
Aug 30 2011
I'm not sure what I am talking about (I have never used interfaces so far), but if a interface developper adds a method foo, she expects every developper of derived class to get an error because they don't implement this new method yet. But if a derived class unfortunately already has a method called foo. The developped of the derived class will not be aware that the interface has changed, and his method foo is propably not what is expected by the interface developper. The compiler will not complain about the absence of the override (or implement?) keyword. This may be a serious problem. The only solution is to never add new interface methods without providing default solutions for these methods. -- Christophe
Aug 30 2011
On 08/29/2011 10:24 PM, Jonathan M Davis wrote:On Monday, August 29, 2011 14:09 Mariusz Gliwiński wrote:+1 override should be required when there already is an implementation and disallowed when there is not.<code> interface Interface { Interface method(); } class Class : Interface { override Class method() {} } </code> DMD complains it isn't overriding. How should it be according to specification, and how about making it legal?It's _not_ overriding. It's implementing an interface method. Those are two totally different things. And I think that it's horrible that Java considers implementing an interface method as overriding it. I'd _hate_ to see that in D.
Aug 30 2011