Class design frustrations moving from Java to ActionScript
I primarily work in Java, but I've recen开发者_如何转开发tly started using ActionScript 3.0 for a multi-player Flash game that I am helping to develop. The project is in it's early stages, so I'm still working on the class structure. I keep running into limitations with the ActionScript language when I try to use many of the OOP features I expect in Java.
For example:
- I need an abstract
Character
class. There is no reason whyCharacter
would ever be instantiated, but ActionScript doesn't support abstract classes. As a result my code has this comment at the top:
Character should be an abstract class, but AS doesn't support abstract classes.
DO NOT CREATE AN INSTANCE OF THIS CLASS. (Only instantiate classes that extend this one (ex. Player, Zombie))
- As a result of the design of Flixel (the library we are using), I need to have a
CharacterGroup
class with an inner classCharacter
so that aCharacterGroup
can also contain other sprites like guns and stuff. In Java, I would use an inner class. ActionScript doesn't support inner classes. There is something called a "helper class", but helper classes are not inherited, which makes them useless in this context.
My question is this: Is ActionScript's ability to deal with OOP design just less developed or am finding ActionScript so frustrating because I am trying to write it as if it were Java instead of working my head around how ActionScript was desinged?
In other words, is the "correct" way of doing OO design different in ActionScript than it is in Java?
(Note: I'm not asking for opinions about why ActionScript is better/worse than Java. I'm only asking if I am coding correctly or trying to pull too much of my experience from Java.)
Thanks!
AS3 is not missing features and you cannot define it as 'less developed'.
Firstly for your problem - there are ways around the abstract class methodology. For your abstract class Character - you can make it so the user developer receives an error on trying to instantiate it.
package com.strangemother.database.abstract
{
public class CentralDispatch extends EventDispatcher
{
private static var _centralDispatch:CentralDispatch;
public static function getInstance():CentralDispatch
{
if(!_centralDispatch)
_centralDispatch = new CentralDispatch(SingletonLock);
return _centralDispatch;
}
public function CentralDispatch(lock:Class)
{
if(!lock is SingletonLock)
{
throw new Error("CentralDispatch is a singleton. Use CentralDispatch.getInstance() to use.");
}
}
}
}
internal class SingletonLock{}
AS you can see - this must be used by the '.getInstance Method' - but to extend of that, only this class can make a new instace of itself as its the only class of which can see the internal class 'SingletonLock{}'. For your purpose - you may remove the 'getInstance()' method and force another way the user to receive an instance of this class.
This should also display the ability to make internal classes. These cannot be seen by any other class - only this package and the parent class CentralDispatch can use it.
Another way you may use the abstract function method - is write then into an interface
package com.strangemother.database.engines
{
import com.strangemother.database.Model;
import com.strangemother.database.ModelSchema;
import com.strangemother.database.events.ModelEvent;
public interface IEngine
{
/**
* Reads modelSchema and calls generateModel upon
* each model found.
* */
function generateModelSchema(modelSchema:ModelSchema=null):String
/**
* Generate your CREATE syntax model to output to your SQL
*
* If you are extending the framework with your own database
* engine, you must override this with your own model generation
* format.
* */
function generateModel(model:Model):String
}
}
then at any point to use this, you implement it at class level
public class SQLite3 extends EngineBase implements IEngine
{
now my SQLite3 class must have the methods defined in IEngine
I much prefer to write classes with defined functions of which are overridden when implemented.
AbstractBase.as
/**
* connect to the database. This is not usually
* required as the abstraction layer should
* automatically connect when required.
* */
public function connect(onComplete:Function=null):void
{
SQLite3 of which extends AbstractionBase at some point
overide public function connect(onComplete:Function=null):void
Now to refute @Allan's comment of it being less developed (Sorry dude)
No operator overloading - thats correct but neither does Java. it wasn't applied to ensure AS3 was readable.
function overloading - You can't hard type it, but you can have function makeTea(...args)
passing in as many or as little data as you wish. you've also got getters/setters.
for inline functions you can create anonymous functions.
var myFunction:Function = Function(name:String):String{ return name + ' - rocks!'; }
You've got dynamic classes therefore class level overloading -
and good example of real code is Flex Lib - it open source and you can read read how all these elements are managed by glacing through the code.
It is somewhat subjective, but personally, I would say that the "correct" way of doing OO design in AS3 is the same as Java and yes AS3 is just less developed.
AS2 was very much prototype based much like JavaScript currently is, althought as with JavaScript you could still program it to fit a classical style. Then along came AS3 which was based off a draft of the ECMAScript edition 4. The update to the ECMAScript made it more classical, akin to Java (JavaScript 2 which was going to be based on it, but was dropped as members of the commitee deemed it changed too much). So while AS3 is now a more classical Java style language, as you have found out, it is light on language features. Off the top of my head it is missing things like:
- operator overloading
- function overloading
- generics
- abstract classes
- inline functions
- inner classes that you pointed out
and probably a lot more things that other languages have that I am not aware of. It is understandable that it is annoying to not be able to use language features that you are used to but most of the time I have come to learn that the things lacking are luxuries*. You can get by without them its just at times can make your code a little more dangerous and verbose and thats just something you have to learn to live with.
There are a few hack ways to try and emulate some of these features but I rarely bother.
*You can also try looking at the language Haxe. The code is compiled to LLVM to ABC bytecode. The Haxe language supports generics, inline functions, conditional compilation (and more). I use it whenever I am writing a library.
精彩评论