Why is this parent subclass method not polymorphic?

I was doing Dlang recently because C ++ just didn't sit right with me after using Python for so long. While I was chatting, I stumbled upon what I thought would be a very simple exercise in polymorphism. I suppose, as you expected, that something will work, and that these are actually two different things for reasons that the end user probably cannot understand. That being said, here is the source code of my "sandbox.D":

import std.stdio; class Animal { string voice = "--silence--"; void speak() { writeln(this.voice); } } class Dog : Animal { string voice = "Whoof!"; } int main() { auto a = new Animal(); auto d = new Dog(); writeln(a.voice); // Prints "--silence--" writeln(d.voice); // Prints "Whoof!" a.speak(); // Prints "--silence--" d.speak(); // Prints "--silence--" NOT "Whoof!" return 0; } 

I think my problem is why the keyword "this" just doesn't work, as you expect, in the C ++ successor language.

+5
source share
2 answers

Methods are polymorphic; variables are not. Therefore, instead of making the voice variable, you want to override speak in the child.

In addition, the return type auto does not work with polymorphism, you need to specify types. (The reason is that automatic return makes a function template in the compiler, which theoretically can have several redefinable slots in the function table, so it just doesn't try to insert it.)

So try this:

 import std.stdio; class Animal { void speak() { // changed to void instead of auto writeln("--silence--"); } } class Dog : Animal { override void speak() { // the override tells it to override the base method writeln("woof"); } } int main() { auto d = new Dog(); d.speak(); return 0; } 

If you have a lot of common functionality and want to reuse a single function with minor changes to child classes, you can make a method instead of a variable that just returns something.

Like string voice() { return "woof"; } string voice() { return "woof"; } , it can be overridden in child elements.

+5
source

Another way is to use a template for this parameter:

 import std.stdio; class Animal { string voice; void speak(this C)() { writeln((cast(C)this).voice); } } class Dog : Animal { string voice = "Whoof!"; } int main() { auto a = new Animal(); auto d = new Dog(); a.speak(); // Prints "" d.speak(); // Prints "Whoof!" return 0; } 

Or when you don’t need a voice as a member:

 import std.stdio; class Animal { static immutable voice = ""; void speak(this C)() { writeln(C.voice); } } class Dog : Animal { static immutable voice = "Whoof!"; } int main() { auto a = new Animal(); auto d = new Dog(); a.speak(); // Prints "" d.speak(); // Prints "Whoof!" return 0; } 
+1
source

All Articles