A nice little set of articles by Henry Zhang and Jim Weaver at O’Reilly’s InsideRia.com detail how Zhang wrote a PacMan game in FX. From the article:
When I was young I was fascinated by arcade games. One of my favorites was the Pac-Man game. Recently, when I was learning the JavaFX language, I decided to write the game in JavaFX. Based on my experience in other programming languages, I assumed there would be some amount of work in building a game such as Pac-Man, giving me a good feel for RIA development in JavaFX.
A quick perusal reveals at least one no-no that we should document better: never subclass the Shape classes. They weren’t meant to be subclassed, and if JavaFX Script gave us “final” we’d have used it. Rather, use a CustomNode. The only three Node classes in JavaFX 1.2 that were intended to be subclassed were CustomNode, Control, and Container.
I’m not sure anything bad will happen to you if you subclass one of the shapes, maybe we’ll relax this restriction in the future. Primarily, we just never intended this usage. But hey, sometimes the best things aren’t intended! Its great to see some detailed examples coming out about JavaFX, can’t wait to see more!
Thanks for the point-out about subclassing Shape – but… why is that a bad thing? Is there a technical reason, or just “we might break it in the future” reason?
I think the ‘final’ modifier in Java is a great way to make your code more robust and it would be nice to see it in JavaFX as well. I logged an issue a while back for making functions final. http://javafx-jira.kenai.com/browse/JFXC-2570. Add your vote if you agree.
That issue just refers to functions but I should have included classes as well.
I think we need to consider carefully whether we really want have a rule that prohibits subclassing of the Shape classes.
There are (at least) two different purposes for subclassing. The first is to modify the behavior of the class, by overriding public methods/functions that the class uses to implement its own behavior. The second is to augment the class with application-specific information, so that there is a natural coupling between the application’s data and the Shape (or whatever) that’s being used to represent it on the screen.
It probably makes sense to prohibit subclassing for the first purpose but to allow the second. The reason the first purpose should be disallowed is that it creates dependencies between application code and the internal implementation of the superclass. This leads to breakage of the superclass’ behavior is modified. Subclassing for the second purpose is usually innocuous and can make application programming quite convenient.
I took a quick look through Henry Zhang’s code, and it looks like he’s mainly subclassing the Shape classes for the second purpose, to augment them with application-specific code and data. That seems OK to me.
It’s overkill to declare that classes cannot be subclassed with something like the ‘final’ modifier in Java, since this prohibits both uses of subclassing, when in fact only the first is dangerous.
Ah, but what if every node had a map, and such a map would fire binding events. Further, what if each map’s elements were treated as a type of dynamic property? In this case, you would get the benefits of the second purpose without having to subclass, and without the cost of another class file?