A while back I posted about Singletons and Abstract Classes in AS3. My basic argument was along the lines of “AS3 doesn’t support them, so chill out and stop trying to force them into existence.” I was probably went a bit too far in that direction. Although I completely disagree that Singletons are one of the “core patterns used in object-oriented programming” (more likely the core overused pattern that breaks object-oriented designs), they do have valid uses. So it’s nice if you are releasing a Singleton class to at least provide a readable error message that says, “Hey, you weren’t supposed to instantiate me. Use getInstance(), bud!”
On the other hand, we have abstract classes. One commenter said,
An OO language without abstract classes is barely an OO language at all. The proper way to think when developing an app OO style is to develop 70% of it in abstract classes, and the rest as instantiable classes. In other words, abstract classes aren’t an afterthought, they’re the thought.
This stuck with me for a while. There are parts of it that are true. You do want to code to interfaces, and abstract classes are an important part of that. On the other hand, leaping though over-engineered hoops to make “abstract” classes non-instantiable just seems stupid to me.
I’m currently reading Kent Beck’s Implementation Patterns and came across this great discussion of abstract classes in Chapter 5. He goes into the importance of coding to an interface, then discusses Java Interfaces and the benefits and problems with them, and then talks about the other method of coding to an interface, using a superclass.
The superclass is abstract in the sense that it can be replaced at runtime with any subclass, whether it is abstract in the Java sense or not.
Further on he talks about “real” abstract classes:
Using the keyword abstract with a class tells readers that they will have to do some implementation work if they want to use the class. If there is any chance to make the root of a class hierarchy useful and instantiable on its own, do so. Once on the path of abstraction, it is easy to go too far and create abstractions that never pay off. Striving to make root classes instantiable encourages you to eliminate abstractions that are unlikely to pull their weight.
Yes, I agree completely. This is what I was getting at, or trying to. Of course you can create subclasses and code to them as interfaces in ActionScript. So what if those base classes are instantiable? The simple fact of them not being non-instantiable is not going to break your application. Sure, if someone creates an instance of an “abstract” class, or fails to implement an abstract method, it’s going to fall back to the base class and do nothing, or whatever default implementation you have. But even still, it shouldn’t break anything. Name it as abstract: AbstractFoo. Foo extends AbstractFoo. If you want to throw some errors in your abstract methods, go for it. If you really think you need it, throw an error in the constructor, as described in various places.
But keep it simple. My original point was not that these things aren’t occasionally needed in AS3, but that page after page and blog post after blog post and argument after argument about the best way to create an airtight, foolproof, perfect abstract class or private constructor was getting ridiculous. Take reasonable measures and get on with it.
And in fact, as Beck describes above, you should actually strive to make your base classes instantiable and eliminate useless abstractions. This is a far cry from “an OO language without abstract classes is barely an OO language at all.”
OK, now I will prepare for the onslaught of angry comments… 🙂
Just have both. That way the programmer can choose and everyone will be happy and peaceful while singing and dancing in the fields.
Until we find some other silly thing to argue about.
I entirely concur. Abstraction, though powerful, is not a central OO concept. A lot of us have wasted so much time just to follow “better practices” now that ActionScript is a serious language, that we’re losing sight of our main goal, which is to make clever stuff on web pages.
If you utilize pseudo-abstract classes in your AS3 projects, who’s going to notice? You? 😛
I still love java in the books
Just get on with it – agreed! Here’s a tangent: I’m increasingly thinking that “object composition” rather than inheritance is the best way to go for coding games etc. Any thoughts on that?
Well said, I couldn’t agree more.
You’re right — jumping through hoops to make your class uninstantiable or singleton is silly. Trace or throw an error — that’s all you really need. What benefit does anything else give you, or your users?
@Iain: There’s an axiom that says “Favor composition over inheritance.” Composition forces you to think about and *use* your public interfaces.
That being said, inheritance is still very important. Composition is a HAS-A relationship, while inheritance is an IS-A relationship. For game objects, inheritance is probably more on track: A PowerupObject IS-A GameObject.
But what about this: class GameObject extends Sprite. Is composition better here? I would say it is — a GameObject HAS-A visual representation. In Flash, instead of extending GameObject from Sprite/MovieClip, I like to have GameObject contain its visual Sprite as a member variable. Using composition/aggregation in this way gives me some benefits: It hides the tons of DisplayObject functions away from the game interface, makes your IDE code hinting clearner, and separates the display of your game from the actual game state (Model-View-Controller)! 🙂
I think abstract classes only need to be strictly “abstract” under the assumption that programmers using those classes are stupid enough to try to instanciate something that wasn’t meant to be instantiated.
I find it interesting that a lot of Actionscripters wrestle with these concepts now. I’m sure other languages have covered the topic “what is true OO” decades ago. I’ve come to the conclusion that it doesn’t matter. Different strokes for different blokes. What matters is transparency. Allowing your code to show enough information to whoever is going to use it. You do so by being consistent in structure and form and I think that is way more important.
Abstract classes are freaking useful. That’s why they exist in other programming languages – they should also exist in ActionScript.
The same goes for Singletons. Why is it that you could make a constructor private in AS2 but not AS3 – it’s nuts.
Ewan, I’m not saying they aren’t useful. Not saying they shouldn’t be there. But they aren’t there. And “useful” doesn’t mean “you couldn’t possibly do without them” or “ActionScript is not a ‘real’ OO language because it doesn’t have them”
It’d be nice if AS3 had abstract classes, but largely for the same reasons it’d be nice if it had multiple inheritance: to save typing. Sometimes you want to create base class that holds functionality for a tree of classes but the base class doesn’t actually do everything it needs to do usefully (DisplayObject and DisplayObjectContainer are *excellent* examples of this). Same with multiple inheritance: I hate it when used a poor replacement for composition, but its a quick-n-easy way to get mix-in functionality.
In regards to games: composition is *way* more favorable to inheritance. In our new game making app, all game objects are decomposed into actions that are composited together. Technically, its implemented as a decorator pattern to make conflict resolution easier, but if the target audience was programmers it’d be a generic object composition framework. Flash’s native event system is *really* handy for these composition frameworks, to the point where I’ve experimented with have all behavioral components subclass Sprite and be literal children of their game object to automagically handle input event propogation, etc.
Troy and Mike – thanks for the feedback, it’s good to know I’m on the right track with this. Where I use inheritance in complex games I end up having to dynamic cast alot, and also end up overriding half the code in my base classes, and it seems “messy”. Much better to divide the code into reusable “behavior” objects (memories of Director!). I’m thinking that my code should look something like this:
if (gameObject.movable)
gameObject.movable.move(5, 5);
One thing I’m not sure of – should I have a variable in my base class (initially set to null) for every possible behavior? Do I only need one base class?
Someone needs to write a tutorial about object composition / aggregation as it relates specifically to Flash (and esp. games). I’ve read a bit about this for C++ games but never for Flash games.
Hello 🙂
For me … not need of abstract class for the moment in AS3 🙂
I prefere speak about “helper” class who implement one or more interfaces.
In VEGAS my framework opensource i use the “getInstance()” method like a “Factory” or a “Locator” method to returns one object singleton in my application. But i can continue to instanciate my class with the new keyword !
In other case, i use the “getInstance()” method with an argument ‘id’ or ‘name’ or ‘channel’… to returns “multi-singleton” objects of my class.
Example :
import flash.events.Event ;
import vegas.events.EventDispatcher ;
function testHandler1( e:Event ):void { trace("test1 : " + e) } ;
function testHandler2( e:Event ):void { trace("test2 : " + e) } ;
// register controllers in my application with multi FrontController singleton reference in my application (multi channel to dispatch the events in the global event flow)
FrontController.getInstance("channel1").insert( "test1" , testHandler1 ) ;
FrontController.getInstance("channel2").insert( "test2" , testHandler2 ) ;
// test - i dispatch the events in 2 channels in my application.
EventDispatcher.getInstance("channel1").dispatchEvent( new Event("test1") ) ;
EventDispatcher.getInstance("channel2").dispatchEvent( new Event("test2") ) ;
I can instanciate my 2 class with the new keyword too 😉 It’s not a problem 🙂
EKA+ 🙂
Good news! I find out this in bugs.adobe.com, it seems the SDK team already working on it
To support full OOP: Abstract method [Status:Open ]
https://bugs.adobe.com/jira/browse/ASC-3379
In response to what Mike Welsh said (and probably of interest to other game devs reading these comments), I don’t I entirely agree, and I think that’s rather a broad and sweeping statement. The example you’ve given makes sense, but a game object can be a lot of different things. There are implementations (like one I’m working on right now) where a game object can be a lot of different things (“has-a” vs “is-a”) at once. For example think of a racing game where you have all sorts of different cars made up of different components that you have bought. This car is assembled from these components (even if not in the more physical sense), eg. it has a particular type of gearbox, particular spoilers, mags, tyres, engine, supercharger etc. There are far too many possible permutations here to predict, thus inheritance is out the window for this type of scenario.
Here is a post on my blog discussing the matter of composition in game frameworks: http://www.visualharmonics.co.uk/actionscript-3/using-function-closures-in-object-composition/
(Hope you don’t mind Keith)
Regards,
-Nick
Oh and a little more…
@Keith, I couldn’t agree more, really. Eliminating derived class cruft is a worthy goal but sometimes (particularly when you doing “evolutionary” development as is the Agile way), it is very difficult to *know* what to shift up to a base/abstract class, and what to keep in the derived classes, until you’ve actually used the thing a bit and it starts to show the form it wants to take, if you can excuse the anthropomorphism.
@Mike Welsh post — In regards to the rest of your post (which I didn’t read fully the first time!) I completely agree, having implemented an MVC game framework in that way myself. It is without doubt the cleanest method, if and when you are able to take the time on it. Sadly, the DisplayObject paradigm in ActionScript confuses a lot of developers in terms of separating controller logic from display logic, and for starting game developers this is really a bad thing if they plan to move onto bigger and better things than Flash games.
Thanks to all for some
no problem at all Nick. I’m glad to have ideas shared. Also added your feed to my netvibes, Looks like you have some interesting stuff there.
Well said, well said.