Problem using Interfce

simendsjo simendsjo at gmail.com
Mon May 14 04:49:21 PDT 2012


On Mon, 14 May 2012 13:08:06 +0200, Stephen Jones <siwenjo at gmail.com>  
wrote:

> I have a Widget interface which I was hoping would allow me to
> subsume a set of classes {Button, Cursor, etc} as being Widgets
> so I could keep an array of buttons, cursors, etc by initializing
> them as Widgets.
>
> private Widget[] widgets;
> ...
> widgets[widx++]=new Button(fmt, unitw, unith, count);
> ...
> widgets[widx++]=new Cursor(unitw, unith, count);
>
>
> But when I try to step through the array I cannot access Button
> or Cursor variables because "Error: no property 'vertStart' for
> type 'Widget.Widget'":
>
> foreach(Widget w; widgets){
>      glDrawArrays(GL_TRIANGLES, w.vertStart, w.vertCount);
> }
>
>
> I am used to languages where the w under consideration in any
> iteration would be known to have been initialized as a Button or
> Cursor, etc, and the value of vertStart would be found without
> error. I cannot cast without wrapping everything in if
> statements. I could use access functions but I would prefer not
> to incur function overhead. Is there a solution?
>

If the language/runtime knows the actual underlying class for the  
interface, some overhead must occur behind the scenes.
This seems more like a design issue. Why doesn't the interface contain  
vertStart etc? Should you have a base class that contains these? Or  
another interface?

import std.algorithm, std.stdio;

interface Widget {} // common widget
class SomeWidget : Widget {}

interface VerticeWidget : Widget { // Might be drawn
     @property int vertStart();
}

class Button : VerticeWidget {
     @property int vertStart() { return 10; }
}

// only fetch VerticeWidgets
@property auto verticeWidgets(Widget[] widgets)
{
     return widgets
         .map!((a) => cast(VerticeWidget)a)()
         .filter!((a) => a !is null)();
}

void main() {
     Widget[] widgets;
     widgets ~= new SomeWidget();
     widgets ~= new Button();
     widgets ~= new SomeWidget();

     // this only includes the Button (prints 10), which has vertStart as  
it derives from VerticeWidget
     foreach(widget; widgets.verticeWidgets)
     {
         writeln(widget.vertStart);
     }
}
/


More information about the Digitalmars-d-learn mailing list