Override Polymorphism versus me and a pot of coffee.
Override Polymorphism versus me and a pot of coffee., Posted in Actionscript 3, June 20th, 2009

JIRA SDK-16960
Java explanation of Late-Binding

The Issue
Subclassing has one purpose, to further specialize. If I want to extend my ‘FarmAnimal’ class and call it ‘Chicken’ that is specialization. If I extend ‘Real-Estate’ with ‘Condo’, that is specialization. So, what if I want to further restrict the acceptable properties of my sub-class? Override polymorphism allows us to redefine a inherited method from our super-class but doesn’t allow us to sub-specialize the method arguments(parameters) and return type. Why is this? If the specialized arguments and return type are fully type-safe against the requirements of the super-class then what is the problem?

The Example
Say my class ‘FarmAnimal’ has a method.

public clone():FarmAnimal {}

Now, I have a class ‘Chicken’ extends ‘FarmAnimal’. ‘Chicken’ has methods associated with it that do not exist in ‘FarmAnimal’. However, when I call chicken.clone() I still get a class instance typed FarmAnimal. Which is correct, it returns a Chicken object typed as FarmAnimal because override polymorphism says so. Now, every time I want to use methods special to Chicken. I have to retype the object as chicken.

chik:Chicken = chicken.clone() as Chicken;

This is ok. Now, what if clone() has a argument.

public FarmAnimal clone(mate FarmAnimal) {}

Thats cool but a Chicken can’t mate with a Pig so we’ve got to do something about this. Override polymorphism says we can’t change the arguments. Wouldn’t it be awesome if we could just re-define clone() as

public clone(mate:Chicken):Chicken {}

Well we can’t. What are our options? Interfaces have the same restrictions. We usually end up abandoning polymorphism completely in order to accomplish the task at hand or creating manual type checking on every override to prevent the wrong type of object being passed. All arguments aside, Chicken is a FarmAnimal so it is theoretically type-safe against the super’s version of makeSpawn. I don’t understand why the rules of polymorphism can’t be adapted to support this type of behavior.

UPDATE: Method Overloading as defined by Late-Binding in Java does partially do what I ask but does not hit the nail on the head because, ultimately, the original version is left intact whereas I would want to disallow it completely and would not be compatible when accessing typed as a Interface.

Any ideas? Hit me up on Twitter.