www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Subclass Type

reply Mason Green <mason.green gmail.com> writes:
Hi, does anyone know how to return a Subclass's type?  I would like to create a
new instance of the subclass based on its type. Here is my example code....

class FooBar {

 
class Foo : FooBar {
       
    this() {
        super(1);
    }
    
    override void printKey() {
        Stdout(key).newline;
    }    
    
}

class Bar : FooBar {

    this() {
        super(2);
    }
    
    override void printKey() {
        Stdout(key).newline;
    }
}

void main() {

    FooBar x = new Foo();
    FooBar y = new typeof(x);
    
    x.key++;
    y.printKey(); // This prints 0. I want it to print 1
    
}

As is, y is created as type FooBar.  Instead I would like to be of type Foo.
i.e the equivalent of:

FooBar y = new Foo();

I've seen this done in other languages such as ActionScript fairly easily:

public function createJoint(data:JointData):Joint
{	
    var c:Class = data.getJointClass();		
    var j:Joint = new c(data) as Joint;
}

In this case, Joint is the superclass.  data.getJointClass returns the subclass
type.  j is created as a new subclass. The normal D equivalent would be:

Joint j = new MouseJoint();  // or some other subclass that getJointClass     
                                        // returns.

Thanks,
Mason
Aug 15 2008
next sibling parent Mason Green <mason.green gmail.com> writes:
Damn, my code was cut off.... here it is again...

class FooBar {

    int key;
    
    this() {
    }
    
    this(int key) {
        this.key = key;
    }
    
    void printKey() {
        Stdout(key).newline;
    }    
}

class Foo : FooBar {
       
    this() {
        super(1);
    }
    
    override void printKey() {
        Stdout(key).newline;
    }    
    
}

class Bar : FooBar {

    this() {
        super(2);
    }
    
    override void printKey() {
        Stdout(key).newline;
    }
}

void main() {

    FooBar x = new Foo();
    FooBar y = new typeof(x);
    
    x.key++;
    y.printKey(); // This prints 0. I want it to print 1
    
}
Aug 15 2008
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Mason Green" <mason.green gmail.com> wrote in message 
news:g83tfo$k14$1 digitalmars.com...
 Hi, does anyone know how to return a Subclass's type?  I would like to 
 create a new instance of the subclass based on its type. Here is my 
 example code....

 class FooBar {


 class Foo : FooBar {

    this() {
        super(1);
    }

    override void printKey() {
        Stdout(key).newline;
    }

 }

 class Bar : FooBar {

    this() {
        super(2);
    }

    override void printKey() {
        Stdout(key).newline;
    }
 }

 void main() {

    FooBar x = new Foo();
    FooBar y = new typeof(x);

    x.key++;
    y.printKey(); // This prints 0. I want it to print 1

 }

 As is, y is created as type FooBar.  Instead I would like to be of type 
 Foo. i.e the equivalent of:

 FooBar y = new Foo();

 I've seen this done in other languages such as ActionScript fairly easily:

 public function createJoint(data:JointData):Joint
 {
    var c:Class = data.getJointClass();
    var j:Joint = new c(data) as Joint;
 }

 In this case, Joint is the superclass.  data.getJointClass returns the 
 subclass type.  j is created as a new subclass. The normal D equivalent 
 would be:

 Joint j = new MouseJoint();  // or some other subclass that getJointClass
                                        // returns.

 Thanks,
 Mason
You can't, at least not easily. It's easy in ActionScript because it's a dynamic, introspective language. D is statically-typed, and since you can't know what subclass something is until runtime, you can't know what static type to use for it. There is Object.factory, which allows you to create an instance of a class from its name, but it's extremely restrictive -- the class must have a no-argument constructor (or use only the automatically-generated no-argument constructor). In your particular situation, you could put an abstract "dup" (duplicate) method in FooBar and implement it in Foo and Bar, so that if you have one instance of a subclass, you can create another instance of the same class by dup'ing it. But in general, runtime type identification is not going to get you very far in D. This doesn't mean you can't solve your problems, it just means you'll have to solve them a different way.
Aug 15 2008
parent Mason Green <mason.green gmail.com> writes:
Jarrett Billingsley Wrote:

 You can't, at least not easily.  It's easy in ActionScript because it's a 
 dynamic, introspective language.  D is statically-typed, and since you can't 
 know what subclass something is until runtime, you can't know what static 
 type to use for it.  
Ah, excellent explanation. Thanks!
 But in general, runtime type identification is not going to get you very far 
 in D.  This doesn't mean you can't solve your problems, it just means you'll 
 have to solve them a different way. 
 
I know how to get around solving the problem, I was just hoping that there was a "quick and easy" way. In any case, I appreciate your explanation and suggestion. Thanks, Mason
Aug 17 2008