static const vector without new actionscript 3 - actionscript-3

I have written some code in Flash Actionscript 3
public class someClass
{
public static const someVector:Vector.<anotherClass> = Vector. <anotherClass> ([staticConstInstance1, staticConstInstance2, staticConstInstance3]);
}
and it works as intended, but if I use the following code which i tried before using above code (The only diffrence is the new Keyword)
public class someClass
{
public static const someVector:Vector.<anotherClass> = new Vector.<anotherClass> ([staticConstInstance1, staticConstInstance2, staticConstInstance3]);
}
then it does not work. Could someone please explain to me why the new Keyword makes the difference here?

The correct way to populate a Vector is:
public static const someVector:Vector.<anotherClass> = new <anotherClass>[staticConstInstance1, staticConstInstance2, staticConstInstance3];
In your first example you just cast an array to a Vector (which I guess would be slower than to populate it properly).

Related

set static const string as default value of a param and encounters error 1047

I have a function like
public function notify(messageKey:String, messageArgs:Array = null, state:String = NotificationState.INFO):void
where
public class NotificationState {
public static const INFO:String = "info";
public static const WARN:String = "warn";
public static const ERROR:String = "error";
public static const SUCCESS:String = "success";
public function NotificationState() {
throw new AbstractClassError();
}
}
And this results in an error 1047:Parameter Initializer Unknown Or Is Not A Compile-time Constant
Obviously the NotificationState.INFO is a constant string, so it should be a compile-time constant isn't it?
Then why does this error happens?
ps, I'm using Flash Builder 4.7
Fairly common problem of the ASC's class dependencies as the dependency analysis does not include default parameter initializers (never has, never will due to circular references that const parameter initializers can cause in ASC).
So if you were directly calling ASC you can just move your NotificationState class in front of your notify class.
Other ways are to place your consts into a different library and include the resulting SWC were they are needed.
You can also defined the consts in the same class as they are needed, kind-of ugly, unless you use the include directive.
Flag your CONST only classes as public final to provide a hint to the compiler.
If your CONST class and the class that is using them as default parameter initializers both do not inherit from another class, extend the class that is using the const initializers from some simple base class. ASC 'tends' to compile super classes after base-only classes even if there are no dependancies.

AS3 Dynamically create an instance of an object

I have a class which contains the following method to place an object on the stage.
public function createBox()
{
var box:Ball1 = new Ball1();
addChild(box);
box.addEventListener(Event.ENTER_FRAME, boxF);
}
What I would like to do is to is pass an object name to the method, and load that object instead, thus allowing me to use the same method for different objects.
A non-working example:
public function createBox( obj )
{
var box:obj = new obj();
addChild(box);
box.addEventListener(Event.ENTER_FRAME, boxF);
}
Is this possible?
Thanks
A more agile version of the existing answer is to use getDefinitionByName(), which allows you to construct a class based on an input string.
Using this function, you can rewrite the method to something like this:
public function produce(className:String):*
{
var type:Class = getDefinitionByName(className) as Class;
return new type();
}
Advanced:
To make this stricter and more maintainable (make it so only certain factories can create certain classes), you can use an interface to build a relationship between a given factory and the classes it can produce. A small example of this follows below.
Say a factory, EnemyFactory, creates objects that you would consider to be enemies in a game. We don't want to be able to create things like pickups, particles and other non-enemy type objects. We can create an interface IEnemyProduct which is implemented by classes that the EnemyFactory is allowed to create. The interface could be as simple as:
public interface IEnemyProduct{}
Which would be implemented by any enemy classes. The EnemyFactory's produce() function can then be modified to a more readable version, like this:
public function produce(enemyClassName:String):IEnemyProduct
{
var type:Class = getDefinitionByName(enemyClassName) as Class;
return new type() as IEnemyProduct;
}
In this case, produce() will return null if the produced class does not implement IEnemyProduct. The goal here is to make it obvious which factories are responsible for which objects, which is a big advantage once the project becomes larger. The use of an interface rather than a base class also means you can implement multiple interfaces and have the class produced by multiple factories.
You could maybe use a simple factory, or something similar:
public class Factory
{
public static function produce(obj:String)
{
if (obj == "obj1")
{
return new obj1();
} else if (obj == "obj2") {
return new obj2();
}
}
}

AS3 Access stage object in singleton returns null

I know singletons are sensitive subjects, but I really don't want to hear anything about that, or what you think about this implementation. This question is not about that.
So, I have implemented a singleton using a static var with the instance.
private static var instance:SomeClass = new SomeClass();
public static function getInstance():SomeClass {
return instance;
}
SomeClass is a class in the library, and inside that one there some instance called someSymbol.
For some reason, when I use SomeClass as a singleton, every time I want to access someSymbol I get Cannot access a property or method of a null object reference. But if I implement SomeClass with regular instantiation the error disappears.
I've tried accessing someSymbol in different ways but I always get the error.
someSymbol.rotation = 0;
and also
var aSymbol = getChildByName("someSymbol");
aSymbol.rotation = 0;
and also
trace(someSymbol); // null
trace(this['someSymbol']); // null
trace(SomeClass.instance.someSymbol); // throws error
So why do I get null when using this singleton implementation, and not when instantiating the class as usual?
Edit:
Thanks to #Marty Wallace answer, I changed my singleton implementation and now it works.
So, instead of instantiating the instance this way:
private static var instance:SomeClass = new SomeClass();
I instead instantiate it the first time getInstance() is called, as #Marty does it.
I don't know exactly what is going on behind the curtains, but it seems as if SomeClass wasn't fully exported when instantiating before the document class is running.
Your example is working fine for me:
public class Singleton
{
private static var _instance:TestClip;
public static function get instance():TestClip
{
if(_instance === null) _instance = new TestClip();
return _instance;
}
}
And TestClip has an inner MovieClip with the instance name inner:
trace(Singleton.instance.inner); // [object MovieClip]
Do you have any luck if you make a class for SomeClass and make a getter for someSymbol like this?
public function get someSymbol():MovieClip
{
return this["someSymbol"];
}

AS3 - References to argument, is that bad?

I read a question on stackoverflow (couldn't find it now) about how variables in a method can be only accessed in that method, but the code still works with the answer being an analogy of a hotel room. In AS3, I believe everything that's not primitive gets passed as a reference. So, the following code would be the same as that question and isn't guaranteed to work?
public class Testy {
private var foo:Array;
public function Testy(input:Array) {
// Allow the whole class to access it
foo = input;
}
public function traceFoo(){
trace(foo);
}
}
Now, foo would be a reference to the input argument in the class' constructor. Is this safe code/good practice? Thanks!
Yes this is safe/good code practice as long as you don't want to manipulate the original Array. If you want to manipulate the original array, allow public access to the array by making it a public var or using a public getter/setter.
What you've described is a property, and is inline with encapsulation of object oriented programming.
This would expose a getter and setter:
package
{
import flash.display.Sprite;
public class Testy extends Sprite
{
private var _foo:Array;
public function get foo():Array
{
return _foo;
}
public function set foo(value:Array):void
{
_foo = value;
}
public function Testy()
{
super();
}
}
}
Also it's better to return _foo.concat() in getter not to break encapsulation.

Actionscript 3: Can someone explain to me the concept of static variables and methods?

I'm learning AS3, and am a bit confused as to what a static variable or method does, or how it differs from a method or variable without this keyword. This should be simple enough to answer, I think.
static specifies that a variable, constant or method belongs to the class instead of the instances of the class. static variable, function or constant can be accessed without creating an instance of the class i.e SomeClass.staticVar. They are not inherited by any subclass and only classes (no interfaces) can have static members. A static function can not access any non-static members (variables, constants or functions) of the class and you can not use this or super inside a static function. Here is a simple example.
public class SomeClass
{
private var s:String;
public static constant i:Number;
public static var j:Number = 10;
public static function getJ():Number
{
return SomeClass.j;
}
public static function getSomeString():String
{
return "someString";
}
}
In the TestStatic, static variables and functions can be accessed without creating an instance of SomeClass.
public class TestStaic
{
public function TestStaic():void
{
trace(SomeClass.j); // prints 10
trace(SomeClass.getSomeString()); //prints "someString"
SomeClass.j++;
trace(SomeClass.j); //prints 11
}
}
A static variable or method is shared by all instances of a class. That's a pretty decent definition, but may not actually make it as clear as an example...
So in a class Foo maybe you'd want to have a static variable fooCounter to keep track of how many Foo's have been instantiated. (We'll just ignore thread safety for now).
public class Foo {
private static var fooCounter:int = 0;
public function Foo() {
super();
fooCounter++;
}
public static function howManyFoos():int {
return fooCounter;
}
}
So each time that you make a new Foo() in the above example, the counter gets incremented. So at any time if we want to know how many Foo's there are, we don't ask an instance for the value of the counter, we ask the Foo class since that information is "static" and applies to the entireFoo class.
var one:Foo = new Foo();
var two:Foo = new Foo();
trace("we have this many Foos: " + Foo.howManyFoos()); // should return 2
Another thing is static functions could only access static variables, and couldn't be override, see "hidden".