digitalmars.D.learn - something "weird" about polymorphism
- funog (28/28) Nov 15 2009 The following code :
- downs (4/38) Nov 15 2009 The behavior here is entirely correct and, in fact, could not happen any...
- funog (7/48) Nov 15 2009 This is the point, I think it should be disallowed (particularly in D,
- Chris Nicholson-Sauls (7/59) Nov 15 2009 Same object, same method, same parameter... but different interface and ...
The following code : ------------------ import std.stdio; class A { void foo(A a) { writefln("A"); } } class B : A { void foo(B b) { writefln("B"); } } void main() { B b = new B; A a = b; assert(a is b); b.foo(b); a.foo(b); } -------------- outputs: B A This is understandable as B.foo doesn't actually overrides A.foo. But somehow it's weird to get different outputs while "a" and "b" are basically the same object. Has anyone else encountered this problem in real life? Will C+++, java act the same way?
Nov 15 2009
funog wrote:The following code : ------------------ import std.stdio; class A { void foo(A a) { writefln("A"); } } class B : A { void foo(B b) { writefln("B"); } } void main() { B b = new B; A a = b; assert(a is b); b.foo(b); a.foo(b); } -------------- outputs: B A This is understandable as B.foo doesn't actually overrides A.foo. But somehow it's weird to get different outputs while "a" and "b" are basically the same object. Has anyone else encountered this problem in real life? Will C+++, java act the same way?The behavior here is entirely correct and, in fact, could not happen any other way. The only improvement would be disallowing declaring methods that shadow but don't override methods in the super class. The inheritance contract that B enters when it inherits from A states that its foo will take any object of type A. Remember: parameters generalize, results specialize. B's foo _cannot_ override A's foo because that would mean you could not use a B in all situations you could use an A, which breaks polymorphism completely.
Nov 15 2009
downs wrote:funog wrote:This is the point, I think it should be disallowed (particularly in D, since shadowing declarations are deprecated). I understand that B.foo doesn't override A.foo, but I mean, you have the same object, the same function (name), the same parameter... and a different result. Well, I'm not a pro so I don't know how error-prone it can be in "real life".The following code : ------------------ import std.stdio; class A { void foo(A a) { writefln("A"); } } class B : A { void foo(B b) { writefln("B"); } } void main() { B b = new B; A a = b; assert(a is b); b.foo(b); a.foo(b); } -------------- outputs: B A This is understandable as B.foo doesn't actually overrides A.foo. But somehow it's weird to get different outputs while "a" and "b" are basically the same object. Has anyone else encountered this problem in real life? Will C+++, java act the same way?The behavior here is entirely correct and, in fact, could not happen any other way. The only improvement would be disallowing declaring methods that shadow but don't override methods in the super class.The inheritance contract that B enters when it inherits from A states that its foo will take any object of type A. Remember: parameters generalize, results specialize. B's foo _cannot_ override A's foo because that would mean you could not use a B in all situations you could use an A, which breaks polymorphism completely.
Nov 15 2009
funog wrote:downs wrote:Same object, same method, same parameter... but different interface and potentially different invariant on that interface. Sometimes this is a Good Thing, sometimes its a Bad Thing. When it is a Bad Thing, you can generally accomplish what you want with "final" -- but certainly not always! Might be another tick on the "advantages" side of using non-virtual interfaces. -- Chris Nicholson-Saulsfunog wrote:This is the point, I think it should be disallowed (particularly in D, since shadowing declarations are deprecated). I understand that B.foo doesn't override A.foo, but I mean, you have the same object, the same function (name), the same parameter... and a different result. Well, I'm not a pro so I don't know how error-prone it can be in "real life".The following code : ------------------ import std.stdio; class A { void foo(A a) { writefln("A"); } } class B : A { void foo(B b) { writefln("B"); } } void main() { B b = new B; A a = b; assert(a is b); b.foo(b); a.foo(b); } -------------- outputs: B A This is understandable as B.foo doesn't actually overrides A.foo. But somehow it's weird to get different outputs while "a" and "b" are basically the same object. Has anyone else encountered this problem in real life? Will C+++, java act the same way?The behavior here is entirely correct and, in fact, could not happen any other way. The only improvement would be disallowing declaring methods that shadow but don't override methods in the super class.
Nov 15 2009