Quick question for the language nuts out there.
Java and C++ both have the notion of covariant return types when overriding.
Typically, the rule is that an overridden method in a subclass can have a return type that is more specific than its superclass, like so (written in AS-like pseudocode).
class Application
{
function getMenu() : Menu
}
class MyApp extends Application
{
override function getMenu() : MyMenu
}
This is allowed because MyApp honors the contract originally specified by the Application class. The getMenu() function is returning a Menu. However, because it is defined as returning a more specific type of Menu, further type checking can be done, and you can get better code hints when you know that you are using an object of type MyApp.
Some languages also allow changing the type of arguments to functions. In these cases, the arguments have to be contravariant, not covariant (wider, not narrower).
class Menu extends UIComponent
{
// blah blah blah
}
class Application
{
function setMenu(newMenu: Menu)
}
class MyApp extends Application
{
override function setMenu(newMenu: UIComponent)
}
The MyApp subclass honors the contract specified by the Application superclass, because it allows you to call setMenu with any object of type Menu. It widens the definition of setMenu to, in this case, allow any UIComponent to be passed in. Callers who were expecting MyApp to behave like a traditional Application would be none the wiser, but callers who knew the special abilities of the MyApp class could take advantage of its super powers.
I would love to add these types of language features to ActionScript, but the problem is that I want to use them for properties, and the usual recipe doesn’t work so well.
class Application
{
function get menu() : Menu;
function set menu(menu: Menu);
}
class MyApp extends Application
{
override function get menu() : MyMenu;
override function set menu(menu: OOPS???);
}
I am not a language guy, but I would love to be able to have the freedom to redefine a read/write property with a covariant (narrower) type. What this means is that setting the property with the wrong value may lead to a runtime exception. However, there are many cases where these values are either only set once (at the creation of an object) or only within controlled situations.
In the example pseudocode above, I’d love to be able to have, for example, a generic “menu” property of Application that I could do generic things with. But within my subclass, I’d like to have the type of the menuproperty be the actual class I’m using for my menu, so I can do things like: myApp.menu.specialFadeEffect() without downcasting.
Any language geeks out there? Is allowing covariant read/write property types when overriding a bad idea?