View mode: basic / threaded / horizontal-split · Log in · Help
December 09, 2012
how to make new C return other static type than C
interface I
{
    void setX(int x);
    int getX();
}

class C : I
{
    int x, y;

    void setX(int x) { this.x = x; }
    int getX()       { return x;   }
    void setY(int y) { this.y = y  }
    int getY()       { return y;   }
}


void main()
{
    auto obj = new C; // Want new C to instantiate obj with 
static type I.
    obj.setX(3);      // Ok, sets x to 3.
    obj.getY();       // Error, not specified in the interface.
}

- Is it possible to enforce, from within the class, a certain 
static interface type or ancestor type when instantiating with 
new? If so, how is it done?
- Also, is it possible for a class to implement multiple 
interfaces and choose static type among them when instantiated, 
based on static class state or arguments passed to the 
constructor?
December 09, 2012
Re: how to make new C return other static type than C
On 12/09/2012 10:23 AM, deed wrote:
> interface I
> {
> void setX(int x);
> int getX();
> }
>
> class C : I
> {
> int x, y;
>
> void setX(int x) { this.x = x; }
> int getX() { return x; }
> void setY(int y) { this.y = y }
> int getY() { return y; }
> }
>
>
> void main()
> {
> auto obj = new C; // Want new C to instantiate obj with static type I.
> obj.setX(3); // Ok, sets x to 3.
> obj.getY(); // Error, not specified in the interface.
> }

new always returns an object of the actual type the programmer 
requested. It is up to the programmer what interface the object needs to 
be used with:

    C obj = new C;

Now the code works because getY() is being called on a C, which does 
have the definition of that function.

> - Is it possible to enforce, from within the class, a certain static
> interface type or ancestor type when instantiating with new? If so, how
> is it done?

Not possible.

> - Also, is it possible for a class to implement multiple interfaces and
> choose static type among them when instantiated, based on static class
> state or arguments passed to the constructor?

Again, it is always the same type of object. That object can be used by 
its many interfaces.

Ali
December 09, 2012
Re: how to make new C return other static type than C
On Sunday, 9 December 2012 at 18:23:15 UTC, deed wrote:
> - Is it possible to enforce, from within the class, a certain 
> static interface type or ancestor type when instantiating with 
> new? If so, how is it done?

No, but you could make the constructor private so new doesn't 
work on it at all, and then use a factory function.

    static I make() { return new C(); }
    private this() {}

    auto obj = new C; // won't compile
    auto obj2 = C.make(); // works, obj2 static type is I

The make function could be a template or whatever and change the 
return type that way.


And, of course, don't forget

I obj = new C();

will always type obj as the interface.
December 09, 2012
Re: how to make new C return other static type than C
Thanks for your replies. How about this:

interface I {}

interface I1 : I
{
    void setx(int x);
    int getx();
    int getSum();
}

interface I2 : I
{
    void sety(int y);
    int gety();
    int getSum();
}

class Impl : I1, I2
{
    int x, y;

    void setx(int x)   { this.x = x;   }
    int getx()         { return x;     }
    void sety(int y)   { this.y = y;   }
    int gety()         { return y;     }
    int getSum()       { return x + y; }
}

class C
{
    I1 i1;
    I2 i2;
    I currentInterface;

    this()
    {
        i1 = new Impl;    // static type I1
        i2 = csat(I2)i1;  // try to refer to same object through 
i2
        currentInterface = i1;
    }

    void switchInterface()   // Could be private and called 
depending on
                             // internal state
    {
        if (currentInterface == i1) { currentInterface = i2; }
        else                        { currentInterface = i1; }
    }

    /* Direct all method calls to the current interface...
       Perhaps opDispatch?
    */
}

void main()
{
    auto c = new C;
    c.setx(5);       // Should set x to 5 through i1
    c.getSum();      // Should return 5. (5 + 0)
    c.sety(3);       // Should not be possible
    c.switchInterface()   // currentInterface is now i2
    c.setx(10);      // Should not be possible
    c.sety(3);       // Should set y to 8 through i2
    c.getSum();      // Should return 8. (5 + 3)
}


- Could this be possible?
- Will i1 and i2 expose different interfaces to the same object?
- How can a method call on an object be directed to an internal 
object/interface?
December 10, 2012
Re: how to make new C return other static type than C
On 12/09/2012 12:02 PM, deed wrote:
> void main()
> {
> auto c = new C;

D is a strongly statically typed language. The type of c is C, period. 
The compiler will compile the following lines of code all under that 
observation.

> c.setx(5); // Should set x to 5 through i1
> c.getSum(); // Should return 5. (5 + 0)
> c.sety(3); // Should not be possible
> c.switchInterface() // currentInterface is now i2

The compiler cannot analyze the implementation of switchInterface(). c 
is still a C.

> c.setx(10); // Should not be possible
> c.sety(3); // Should set y to 8 through i2
> c.getSum(); // Should return 8. (5 + 3)
> }
>
>
> - Could this be possible?

Not as you have shown.

> - Will i1 and i2 expose different interfaces to the same object?

Yes but it looks like they are not helping with what you are trying to 
achieve.

> - How can a method call on an object be directed to an internal
> object/interface?

Sometimes explicitly:

class C
{
    Member m;

    void foo()
    {
        m.foo();
    }
}

Sometimes automatically by alias this:

class C
{
    Member m;

    alias m this;
}

There must be other more suitable methods depending on the situation.

Ali
Top | Discussion index | About this forum | D home