var w2 = openWindow(FancyWindow);
w2.fancyFn();// Error, class BaseWindow has no field fancyFN
This is expected, thanks to how type inference works.
Remember, openWindow() declares its return type as BaseWindow, even if it always returns FancyWindow. That means that when Haxe goes to infer the type of w2, it concludes it’s a BaseWindow.
Let’s simplify it a bit, by going back to w1.
var w1 = new FancyWindow();
w1.fancyFn();// works fine
That works fine because w1 has type FancyWindow. But what if it didn’t?
var w1 : BaseWindow = new FancyWindow();// works fine
w1.fancyFn();// Error, class BaseWindow has no field fancyFN
That’s right: even though it’s still a FancyWindow, if we tell the compiler to treat it as a BaseWindow, the compiler will act like it’s a BaseWindow.
Why would you do that? Because maybe you’ll want to change w1. Maybe you’ll want to replace it with a plain old BaseWindow, or maybe you want to use a different subclass. As long as it’s declared as a BaseWindow, you won’t run into any issues with this. (And by the way, that other subclass wouldn’t have a function named fancyFN(), so it’s a good thing the compiler lets you know.)
Now to fix the error. There are two things you can do here.
The safe option is to declare that openWindow() returns FancyWindow. Because if that’s the only thing it returns, why not?
public function openWindow() : FancyWindow {
return new FancyWindow();
}
The less-safe option is to use a cast. If openWindow() returns something other than a FancyWindow, you’ll get a runtime error. Otherwise, it’ll work fine.
var w2 : FancyWindow = cast(openWindow(FancyWindow), FancyWindow);