www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get child class Type and members from parent class?

reply zoujiaqing <zoujiaqing gmail.com> writes:
import std.stdio;


class A
{
     this(T)(T t)
     {

     }

     void write()
     {
         T _this = cast(T) this;
         writeln(this.v);
     }
}

class B : A
{
     string v = "hello";
}

void main()
{
     auto b = new B;

     writeln(b.write()); // print hello
}
Nov 20 2019
next sibling parent mipri <mipri minimaltype.com> writes:
On Wednesday, 20 November 2019 at 10:05:11 UTC, zoujiaqing wrote:
 import std.stdio;


 class A
 {
     this(T)(T t)
     {

     }

     void write()
     {
         T _this = cast(T) this;
         writeln(this.v);
Here, class A knows that a 'v' member is present. So why not just put that member in class A, and let B inherit it? If this method won't apply to some other child classes, you can have an intermediate class that adds the v member and specializes this method to use it, and all the v children can inherit from A through that intermediary. I think what you're wanting to do is a reversal of OO design. Maybe you can use proper OO instead, or maybe you'd prefer a discriminated union if different children will have different types for v. Like in an FP lang: https://github.com/pbackus/sumtype
     }
 }

 class B : A
 {
     string v = "hello";
 }

 void main()
 {
     auto b = new B;

     writeln(b.write()); // print hello
 }
Nov 20 2019
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On Wednesday, 20 November 2019 at 10:05:11 UTC, zoujiaqing wrote:
 import std.stdio;


 class A
 {
     this(T)(T t)
     {

     }

     void write()
     {
         T _this = cast(T) this;
         writeln(this.v);
     }
 }

 class B : A
 {
     string v = "hello";
 }

 void main()
 {
     auto b = new B;

     writeln(b.write()); // print hello
 }
You can use a template this parameter [1], like this: import std.stdio; class A { void write(this T)() { T self = cast(T) this; writeln(self.v); } } class B : A { string v = "hello"; } void main() { auto b = new B; b.write(); } [1] https://dlang.org/spec/template.html#template_this_parameter -- /Jacob Carlborg
Nov 20 2019
parent reply Matheus <matheus gmail.com> writes:
On Wednesday, 20 November 2019 at 13:46:07 UTC, Jacob Carlborg 
wrote:
 On Wednesday, 20 November 2019 at 10:05:11 UTC, zoujiaqing 
 wrote:
 import std.stdio;


 class A
 {
     this(T)(T t)
     {

     }

     void write()
     {
         T _this = cast(T) this;
         writeln(this.v);
     }
 }

 class B : A
 {
     string v = "hello";
 }

 void main()
 {
     auto b = new B;

     writeln(b.write()); // print hello
 }
You can use a template this parameter [1], like this: import std.stdio; class A { void write(this T)() { T self = cast(T) this; writeln(self.v); } } class B : A { string v = "hello"; } void main() { auto b = new B; b.write(); } [1] https://dlang.org/spec/template.html#template_this_parameter -- /Jacob Carlborg
I'm not the OP but a lurker, and this is new to me, I mean in your example you're accessing a member "v" which wasn't defined in the Parent class. So if someone creates something like this: class C : A{ string x = "world"; // x instead of v } Not the "x" instead of "v", of course it will only get an compiler error if that function is called in by "C" object. I think this is a powerful and weird feature at the same time, because some could write a code like this: import std.stdio; class A{ void write(this T)(){ T self = cast(T) this; writeln(self.v); } void write2(this T)(){ T self = cast(T) this; writeln(self.x); } } class B : A{ string v = "hello"; } class C : A{ string x = "world"; } void main(){ auto b = new B; b.write(); auto c = new C; c.write2(); } This is a different way of designing things, do people use this often? Matheus.
Nov 20 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 20 November 2019 at 20:57:56 UTC, Matheus wrote:
 This is a different way of designing things, do people use this 
 often?
This is really only useful sometimes. It is important to notice that if you do class C : I {} I c = new C(); c.something(); the template this there will show I, not C. All it means is this is being called on an object of that *static* type. So it isn't really a substitute for traditional virtual functions. Sometimes appropriate to use, just often not.
Nov 20 2019
parent zoujiaqing <zoujiaqing gmail.com> writes:
On Wednesday, 20 November 2019 at 22:26:17 UTC, Adam D. Ruppe 
wrote:
 On Wednesday, 20 November 2019 at 20:57:56 UTC, Matheus wrote:
 This is a different way of designing things, do people use 
 this often?
This is really only useful sometimes. It is important to notice that if you do class C : I {} I c = new C(); c.something(); the template this there will show I, not C. All it means is this is being called on an object of that *static* type. So it isn't really a substitute for traditional virtual functions. Sometimes appropriate to use, just often not.
Thanks every friends :)
Nov 21 2019