On Mon, 14 May 2012 13:08:06 +0200, Stephen Jones <siwe...@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);
}
}
/