Installment 4 of my series on Object Oriented Programming with ActionScript 2.0 will cover dynamic classes – a relatively simple topic, but one worth being familiar with so as to avoid frustration.
Again, if you haven’t read the previous posts, you should because they all build on one another. Also, if you want all the nitty gritty details, you’ll have to buy “Flash MX 2004 Demystified”, which is forthcoming from Macromedia Press.
By default, the actionscript 2 compiler in FlashMX 2004 will not allow you to add new properties or methods to instances of a class. Attempting to do so will result in a compiler error.
Read on…
For example, if we were to continue with the code from the previous example (using the GThing class), and we tried to add a property to a GThing instance in the FLA like so:
myG:GThing = new GThing("superman"); myG.outift = "tights'n'cape"; |
We would be faced with this compiler error:
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 2: There is no property with the name ‘outfit’.
Again, this is only enforced by the compiler, and is easy to circumvent, but it makes for a nice reminder to apply good OOP practice.
Say you want to create a class that allows you to add members to its instances, without generating errors. This is called a dynamic class, and is indicated by prefixing the class name with “dynamic”.
For example:
dynamic class GThing { var myName:String; function getGreeting(p_salutation:String):String { return p_salutation+" "+myName; } function GThing(p_myName) { myName = p_myName; } } |
Now if you compile the FLA again, it will run without generating a compiler error.
More to come…
Not a comment specific to this posting but I am just wondering in general how many people are really using Flash in a true OOP fashion to build applications (RIA’s) as opposed to using Flash to build fancy looking websites with lots of eye candy.
I have been doing a lot of application development in Flash over the past year and everywhere I look I do not see many others using Flash as a platform to build app’s on. I have seen a few really good examples here and there (gModeller is one of the better ones) but I wonder how much Flash as a real development platform has really caught on.
Has anyone figured out a decent way to extend static objects in AS2?
I had this funtion previously,
Key.isUp = function(keyCode) {
return (Key.isDown(keyCode) == false);
}
and converted it easily to,
var k = Key;
k.isUp = function(keyCode) {
return (Key.isDown(keyCode) == false);
}
but doing,
k.isUp(Key.ENTER);
still gives a compiler error 🙁
Latvian translation:
http://www.flash.lv/news/articles/article.php?id=9774
Chinese Translations 🙂
http://dengjie.com/gskinner/oop_series.swf
Dynamic classes are probably best reserved for just making something work, after you have most likely designed something too restrictively.
They’re not good to use, in general, because you lose all the benefits of strong typing.
Your example is a case in point because you have misspelled “outfit” as “outift”. The compiler won’t complain, but your code won’t work either. If you had not used a dynamic class, but instead declared outfit as a member, then it would have generated errors – and quite helpfully too!
korean translation
http://www.feople.com/run/oo/view.php?id=crazymew&no=298
OOP4AS2#4: clases dinámicas
El capítulo 4 de la serie sobre Programación Orientada a Objetos con ActionScript 2.0 tratará sobre clases dinámicas – un tema bastante simple, pero con el que vale la pena estar familiarizado para evitar frustración.
Nuevamente, si no has leído los c…
Spanish translation:
http://blog.innocuo.com/index.php?p=30&more=1&c=1&tb=1&pb=1#more30
This article is now available in german!
Check it out at:
http://www.urbanspice.de/blog/archives/000013.html
Dutch translation: http://www.flashpro.nl/detail.asp?ID=137
On Peter’s comment:
“They’re not good to use, in general, because you lose all the benefits of strong typing.”
I read something about this in the help files, too:
“Type checking on dynamic classes is less strict than type-checking on nondynamic classes, because members accessed inside the class definition and on class instances are not compared to those defined in the class scope.”
However, my initial experiments don’t show this.
// Cat.as
dynamic class Cat {
var __color:String = “black”;
function set color (newColor:String):Void {
__color = newColor;
}
function get color ():String {
return __color;
}
}
// myCat.fla
var myCat:Cat = new Cat();
trace(myCat.color); // black
myCat.color = “white”;
trace(myCat.color); // white
myCat.color = 0xFFFFFF; // error type mismatch
myCat.__color = 0xFFFFFF; // error type mismatch
I get the type mismatch error whether setting the __color attribute directly or going through the set function. Where does the strong typing not work here?
OK, I get it. Strong typing not work for new members that you add to the dynamic class.
Quirks of Dynamic Classes
I’ve been converting some of my AS1.0 classes over to AS2.0 and I’ve run across a few quirks.
The first has to do with the for…in construct causing compiler errors when iterating through properties on certain classes. It all seems to come down to dy…
I have a very complex flash AS2 problem but the dynamic class help in this article has taken me a lot closer to solving it.
We are developing an application all with classes as you know not having hardly and code on the time line just some to instantiate the main ‘core’ class with, and an external swf library of all the other classes (for example imageclass and videoclass) with various functions that need to happen in those.
These, I should mention are also loaded via a movieclip loader on the main timeline.
The timeline has a frames loaded loop while all the other classes and mx components such as MediaDisplay, MediaController are imported with dummy instances on the stage, thats not
a problem and sounds fairly self explanatory I hope.
I start it all off at the end of the timeline’s loading with:
import core;
core.Main();
//other classes in external swf are imageclass, videoclass
The problem is in the core class, creating instances , as many as we need of each individual class object.
I loop through a list of the objects to place on stage which looks like this but I’ve greatly simplified it for you…
class core extends MovieClip {
private var newthings:Object;
private var target_mc:MovieClip;
// constructor
public function core (target:MovieClip) {
target_mc = target;
var newthings = {image01:
{type:’imageclass’, x:10, y:10, width:100, height:200, file:’myimage.jpg’},
image02:
{type:’imageclass’, x:10, y:210, width:100, height:100, file:’otherimage.jpg’},
video01:
{type:’videoclass’, x:10, y:400, file:’vid1.flv’}
};
//now – to loop through my list and create instance of each class is the tricky bit.
for (var i in newthings) {
// get the params object for each item
var myparams:Object = newthings[i];
// I need a holder clip for each class to live in
target_mc.createEmptyMovieClip(i, target_mc.getNextHighestDepth());
target_mc._x = myparams.x;
target_mc._y = myparams.y;
target_mc._width = myparams.width;
target_mc._height = myparams.height;
//still looking ok? the problem is about to start
//get the classname we need to instantiate
var classname = myparams.type;
// thats fine but now i need a dynamic name for each instance to refer to later, and the calling of the new command dynamically is fiddly but works
// i’ve tried this, which is about as close as I can get
// I make a new instance variable dynamically which has an individual name
// note I cannot datatype it dynamically so just ignore that option
// ideally the line would be var image01:imageclass = new imageclass(target_mc[i], myparams.file);
//
var depth:Number = 1;
this[i] = new _global[classname](target_mc[i], depth, myparams);
// And hey presto i’ve checked the classes and the listing of the object in the flash debugging – all gets created,
// but for some reason nothing appears –
// however the following line works with _root instead of target_mc[i]
this[i] = new _global[classname](_root , depth, myparams.file);
//any clues? why I cant pass a dynamically created clip into the new classinstance to become its target_mc
// in the same way that core’s main recieves _root as its target_mc?
// stuck! and my brain is friend and there is no help anywhere!
}
} // end constructor
public function Main():Void {
var coreInstance:core = new core(_root);
}
}
So if it makes sense and anything springs to mind, please have a little think for some pointers, hopefully some flash guru will get back to me!
Regards
Steve
Vietnam tours operator, vietnam hotels reservation, vietnam resorts reservation, vietnam ticket, property & car rental…