www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Weird behavior of "this" in a subclass, I think?

reply "seashell86" <herp derp.com> writes:
So I've been mostly just toying around with D as it seems like it 
will end up being a strong language for game development both now 
and even moreso in the future.  That being said, I'm perplexed by 
using this code and not receiving the result I would imagine. 
Here is the source code of a basic "sandbox.d" file:

     import std.stdio;

     class Animal {
         string voice;

         void speak() {
             writeln(this.voice);
         }
     }

     class Dog : Animal {
         string voice = "Whoof!";
     }

     int main() {
         auto a = new Animal();
         auto d = new Dog();

         a.speak(); // Prints ""
         d.speak(); // Prints "" instead of "Whoof!"

         return 0;
     }

I know that C++ behaves this way.  However, Dlang impresses me by 
having a very "no duh" approach to things where this type of 
example seems very "no duh."  Anyways, please be gentle as I am 
hardly what most would consider a "skilled" programmer and, as 
such, was something I wanted to bounce off the pros :)
Jul 15 2015
next sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Jul 16, 2015 at 12:18:30AM +0000, seashell86 via Digitalmars-d-learn
wrote:
 So I've been mostly just toying around with D as it seems like it will
 end up being a strong language for game development both now and even
 moreso in the future.  That being said, I'm perplexed by using this
 code and not receiving the result I would imagine. Here is the source
 code of a basic "sandbox.d" file:
 
     import std.stdio;
 
     class Animal {
         string voice;
 
         void speak() {
             writeln(this.voice);
         }
     }
 
     class Dog : Animal {
         string voice = "Whoof!";
     }
 
     int main() {
         auto a = new Animal();
         auto d = new Dog();
 
         a.speak(); // Prints ""
         d.speak(); // Prints "" instead of "Whoof!"
 
         return 0;
     }
 
 I know that C++ behaves this way.  However, Dlang impresses me by
 having a very "no duh" approach to things where this type of example
 seems very "no duh."  Anyways, please be gentle as I am hardly what
 most would consider a "skilled" programmer and, as such, was something
 I wanted to bounce off the pros :)
The reason is that class variables cannot be overridden, only class methods can. If you want to simulate overriding of class variables, you can use a property method instead: class Animal { property string voice() { return "Wah!"; } void speak() { writeln(voice); } } class Dog : Animal { override property string voice() { return "Whoof!"; } } T -- Indifference will certainly be the downfall of mankind, but who cares? -- Miquel van Smoorenburg
Jul 15 2015
next sibling parent "Mike Parker" <aldacron gmail.com> writes:
On Thursday, 16 July 2015 at 00:39:29 UTC, H. S. Teoh wrote:

 If you want to simulate overriding of class variables, you can 
 use a  property method instead:

 	class Animal {
 		 property string voice() { return "Wah!"; }
 		void speak() { writeln(voice); }
 	}

 	class Dog : Animal {
 		override  property string voice() { return "Whoof!"; }
 	}
Alternatively: class Animal { protected string voice; void speak() { writeln(voice); } } class Dog : Animal { this() { voice = "Whoof!"; } }
Jul 15 2015
prev sibling parent reply "seashell86" <herp derp.com> writes:
On Thursday, 16 July 2015 at 00:39:29 UTC, H. S. Teoh wrote:
 On Thu, Jul 16, 2015 at 12:18:30AM +0000, seashell86 via 
 Digitalmars-d-learn wrote:
 [...]
The reason is that class variables cannot be overridden, only class methods can. If you want to simulate overriding of class variables, you can use a property method instead: class Animal { property string voice() { return "Wah!"; } void speak() { writeln(voice); } } class Dog : Animal { override property string voice() { return "Whoof!"; } } T
Wow, a quick and thorough response! Thank you! I'm actually curious as to why this feature would not be in the language? Is it for performance reasons?
Jul 15 2015
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Thursday, July 16, 2015 01:20:10 seashell86 via Digitalmars-d-learn wrote:
 On Thursday, 16 July 2015 at 00:39:29 UTC, H. S. Teoh wrote:
 On Thu, Jul 16, 2015 at 12:18:30AM +0000, seashell86 via
 Digitalmars-d-learn wrote:
 [...]
The reason is that class variables cannot be overridden, only class methods can. If you want to simulate overriding of class variables, you can use a property method instead: class Animal { property string voice() { return "Wah!"; } void speak() { writeln(voice); } } class Dog : Animal { override property string voice() { return "Whoof!"; } } T
Wow, a quick and thorough response! Thank you! I'm actually curious as to why this feature would not be in the language? Is it for performance reasons?
I've never heard of a language that overloaded member variables, and given how class polymorphism works, I don't see how it would even be possible without making it so that all accesses to a variable actually call a function to access it, which would needlessly inefficient (polymorphism works by looking up the correct function in the class' virtual table, and the call site isn't going to know at compile time what class it's actually operating on, so all of that has to be done at runtime). And if you really want something approximating overriding variables, then you can just use property functions to access the variable rather than accessing it directly, and then you can override the property functions. - Jonathan M Davis
Jul 16 2015
parent Jacob Carlborg <doob me.com> writes:
On 2015-07-16 09:46, Jonathan M Davis via Digitalmars-d-learn wrote:

 I've never heard of a language that overloaded member variables, and given
 how class polymorphism works, I don't see how it would even be possible
 without making it so that all accesses to a variable actually call a
 function to access it, which would needlessly inefficient (polymorphism
 works by looking up the correct function in the class' virtual table, and
 the call site isn't going to know at compile time what class it's actually
 operating on, so all of that has to be done at runtime). And if you really
 want something approximating overriding variables, then you can just use
 property functions to access the variable rather than accessing it directly,
 and then you can override the property functions.
In Scala all public instance variables are implemented as methods, if I recall correctly. -- /Jacob Carlborg
Jul 16 2015
prev sibling parent Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
On Thu, 16 Jul 2015 00:18:30 +0000
seashell86 via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 So I've been mostly just toying around with D as it seems like it 
 will end up being a strong language for game development both now 
 and even moreso in the future.  That being said, I'm perplexed by 
 using this code and not receiving the result I would imagine. 
 Here is the source code of a basic "sandbox.d" file:
 
      import std.stdio;
 
      class Animal {
          string voice;
 
          void speak() {
              writeln(this.voice);
          }
      }
 
      class Dog : Animal {
          string voice = "Whoof!";
      }
 
      int main() {
          auto a = new Animal();
          auto d = new Dog();
 
          a.speak(); // Prints ""
          d.speak(); // Prints "" instead of "Whoof!"
 
          return 0;
      }
 
 I know that C++ behaves this way.  However, Dlang impresses me by 
 having a very "no duh" approach to things where this type of 
 example seems very "no duh."  Anyways, please be gentle as I am 
 hardly what most would consider a "skilled" programmer and, as 
 such, was something I wanted to bounce off the pros :)
You can use template this parametr 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; }
Jul 15 2015