[Vala] Create an instance of a derived class, from a base class method



Hi,

I am trying to craft a base class method, that is able to create an
object of the same class as whatever derived-class object it was
called on.

For example, if classes Bar and Baz both derive from Foo, and Foo has
a create() method, then bar.create() should give me an instance of
Bar, and Baz.create() should give me an instance of Baz.

I've spent so long happily experimenting with this that I forgot the
original requirement. but I have come up with two approaches that
almost work (below).

Everything is fine at run-time, but I have to resort to ugly casts
like "Derived obj = derived.foo() as Derived" to get valac to accept
it.

I think the return type ('Base') of foo() is my problem, but I'm at a
loss as to what to replace it with to make this work.

Is there a better way to achieve this sort of thing?




public class Base : GLib.Object {
    public Base foo() {
        Type t = this.get_type();
        return Object.new(t) as Base;
    }
}

public class Derived : Base {
    public void test() {
        stdout.printf("I am an instance of Derived!\n");
    }
}

/********************************************************************************/

/* second attempt with abstract methods */
public abstract class Base2 : GLib.Object {
    public Base2 foo() {
        return new_instance();
    }
    protected abstract Base2 new_instance();

}

public class Derived2 : Base2 {

    /* return type has to be Base2 or vala won't allow the override */
    public override Base2 new_instance() {
        return new Derived2();
    }

    public void test() {
        stdout.printf("Derived2: I am an instance of Derived2!\n");
    }
}


/********************************************************************************/


public static int main(string[] args) {

#if false
    Derived derived = new Derived();
    Derived obj = derived.foo(); // 'cannot convert from Base to Derived?'
#else
    Derived derived = new Derived();
    Derived obj = derived.foo() as Derived; // ugly!
#endif

    Type t = obj.get_type();
    stdout.printf("Type of obj is %s\n", t.name());
    obj.test();


    /* second attempt with abstract methods */
#if false
    Derived2 derived2 = new Derived2();
    Derived2 obj2 = derived2.foo(); // 'cannot convert from Base to Derived?'
#else
    Derived2 derived2 = new Derived2();
    Derived2 obj2 = derived2.foo() as Derived2; // ugly!
#endif

    Type t2 = obj2.get_type();
    stdout.printf("Type of obj2 is %s\n", t2.name());
    obj2.test();


    return 0;
}


cheers
ant



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]