digitalmars.D.learn - how is this considered hiding methods?
- Gor Gyolchanyan (45/45) Sep 22 2012 Can someone please tell me why the following code gives these
- Gor Gyolchanyan (26/72) Sep 22 2012 I figured it out:
- Jonathan M Davis (20/68) Sep 22 2012 The problem goes away if you add
- Andrej Mitrovic (31/34) Sep 22 2012 http://dlang.org/hijack.html
- Andrej Mitrovic (61/62) Sep 22 2012 But I do think this can be further improved in the language. Take this
- Andrej Mitrovic (2/3) Sep 22 2012 Sorry that should be "the Bar class".
- Andrej Mitrovic (3/5) Sep 22 2012 Although this would be kind of counter-intuitive since 'super' already
Can someone please tell me why the following code gives these errors? Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal animal_) hidden by BirdZoo is deprecated Error: class main.ParrotZoo use of main.VertebrateZoo.take(Animal animal_) hidden by ParrotZoo is deprecated /// The code: class Animal { } class Vertebrate { } class Bird: Animal { } class Parrot: Bird { } class VertebrateZoo { void take(Animal animal_) { if(auto vertebrate = cast(Vertebrate)animal_) take(vertebrate); } abstract void take(Vertebrate vertebrate_); } class BirdZoo: VertebrateZoo { override void take(Vertebrate vertebrate_) { if(auto bird = cast(Bird)vertebrate_) take(bird); } abstract void take(Bird bird_); } class ParrotZoo: BirdZoo { override void take(Bird bird_) { if(auto parrot = cast(Parrot)bird_) take(parrot); } abstract void take(Parrot parrot_); }
Sep 22 2012
On Saturday, 22 September 2012 at 07:48:02 UTC, Gor Gyolchanyan wrote:Can someone please tell me why the following code gives these errors? Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal animal_) hidden by BirdZoo is deprecated Error: class main.ParrotZoo use of main.VertebrateZoo.take(Animal animal_) hidden by ParrotZoo is deprecated /// The code: class Animal { } class Vertebrate { } class Bird: Animal { } class Parrot: Bird { } class VertebrateZoo { void take(Animal animal_) { if(auto vertebrate = cast(Vertebrate)animal_) take(vertebrate); } abstract void take(Vertebrate vertebrate_); } class BirdZoo: VertebrateZoo { override void take(Vertebrate vertebrate_) { if(auto bird = cast(Bird)vertebrate_) take(bird); } abstract void take(Bird bird_); } class ParrotZoo: BirdZoo { override void take(Bird bird_) { if(auto parrot = cast(Parrot)bird_) take(parrot); } abstract void take(Parrot parrot_); }I figured it out: class BirdZoo: VertebrateZoo { alias VertebrateZoo.take take; override void take(Vertebrate vertebrate_) { if(auto bird = cast(Bird)vertebrate_) take(bird); } abstract void take(Bird bird_); } class ParrotZoo: BirdZoo { alias BirdZoo.take take; override void take(Bird bird_) { if(auto parrot = cast(Parrot)bird_) take(parrot); } abstract void take(Parrot parrot_); }
Sep 22 2012
On Saturday, September 22, 2012 09:49:04 Gor Gyolchanyan wrote:Can someone please tell me why the following code gives these errors? Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal animal_) hidden by BirdZoo is deprecated Error: class main.ParrotZoo use of main.VertebrateZoo.take(Animal animal_) hidden by ParrotZoo is deprecated /// The code: class Animal { } class Vertebrate { } class Bird: Animal { } class Parrot: Bird { } class VertebrateZoo { void take(Animal animal_) { if(auto vertebrate = cast(Vertebrate)animal_) take(vertebrate); } abstract void take(Vertebrate vertebrate_); } class BirdZoo: VertebrateZoo { override void take(Vertebrate vertebrate_) { if(auto bird = cast(Bird)vertebrate_) take(bird); } abstract void take(Bird bird_); } class ParrotZoo: BirdZoo { override void take(Bird bird_) { if(auto parrot = cast(Parrot)bird_) take(parrot); } abstract void take(Parrot parrot_); }The problem goes away if you add alias VertebrateZoo.take take; It also goes away if you change take in the derived class to take Animal. My guess is that the problem is that the version of take which takes an Animal is unavailable in the derived classes and is therefore "hidden." Any time that you add an overload to a derived class which does not exactly override a function in the base class, the base class overload is hidden in the derived class. The normal fix for this is to alias the base class version in the derived class. But why the compiler would now require that you do that, I don't know. If that's the way that thnigs currently are, it starts to become a bit odd that the base class functions aren't automatically available. IIRC, the reason that they weren't before is so that you don't get cases where you're not aware of what all of the overloads in a class are and end up with a different function being called than you expected (so it's another one of the function-hijacking prevention features), and I that still applies, so I guess that that's why still have to do it. Still, it's weird. TDPL may explain this. I don't know. I'd have to go digging. I'm 99.99% certain that it explains the alias bit at least. - Jonathan M Davis
Sep 22 2012
On 9/22/12, Jonathan M Davis <jmdavisProg gmx.com> wrote:But why the compiler would now require that you do that, I don't know. If that's the way that thnigs currently are, it starts to become a bit odd that the base class functions aren't automatically available.http://dlang.org/hijack.html There's a good reason why, consider: class Foo { void foo(int) { } } class Bar : Foo { alias super.foo foo; void foo(double) { } } void main() { auto bar = new Bar; bar.foo(1); // calls Foo.foo } Now let's say Foo is a library class and you upgrade to a new version of the library without realizing that the base method was removed: class Foo { } class Bar : Foo { alias super.foo foo; // error void foo(double) { } } This now becomes a compile-time error. Without using the alias which triggers the error the literal "1" would be implicitly converted to a double and you'd end up invoking your own 'foo' method (which is no longer an overload).
Sep 22 2012
On 9/22/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:using the aliasBut I do think this can be further improved in the language. Take this for example: import std.stdio; class Foo { void meth(double) { writeln("Foo.meth"); } } class Bar : Foo { alias super.meth meth; void meth(int) { writeln("Bar.meth"); } } class Doo : Bar { alias super.meth meth; void meth(long) { writeln("Doo.meth"); } } void main() { auto doo = new Doo; doo.meth(1); // calls Bar.meth } Now let's say the Doo clas removes the meth overload and the alias: class Foo { void meth(double) { writeln("Foo.meth"); } } class Bar : Foo { // gone } class Doo : Bar { alias super.meth meth; void meth(long) { writeln("Doo.meth"); } } void main() { auto doo = new Doo; doo.meth(1); // now calls Doo.meth } We might have wanted the "super alias" in Doo to only work against the Bar base class so the compiler can notify us if Doo.meth is removed. The language doesn't have a way to warn us of this. I would prefer if "super.alias" meant to take overloads of all base classes into account and that we could use "ClassName.alias" to only import the overload set of a specific base class. That way this would trigger a CT error: class Foo { void meth(double) { writeln("Foo.meth"); } } class Bar : Foo { } class Doo : Bar { alias Bar.meth meth; // error: no overload set in Bar void meth(long) { writeln("Doo.meth"); } }
Sep 22 2012
On 9/22/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Now let's say the Doo clas removes the meth overload and the alias:Sorry that should be "the Bar class".
Sep 22 2012
On 9/22/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:I would prefer if "super.alias" meant to take overloads of all base classes into account.Although this would be kind of counter-intuitive since 'super' already means the direct base class.
Sep 22 2012