compiler error when trying to use addEventListener via interface - actionscript-3

Trying to use addEventlistener with an interface, but i get a compiler error :
=> Call to a possibly undefined method addEventListener through a reference with static type IScene.
//IScene.as
public interface IScene
{
function show():void
function load():void;
function unload():void;
}
//Main.as
var scene:IScene ;
scene= sceneView_Arr[scene_number] ;
scene.addEventListener( GameEvent.ON_LOAD_SCENE , start );
scene.load();
scene.show();
How should i achieve it then ?

Instead of Fox in socks answer, I would recommend a slightly different approach:
public interface IScene extends IEventDispatcher
And then for your actual scene classes
public class MyScene extends EventDispatcher implements IScene
And then you can use it as you already have, without any additional code.
scene.addEventListener(GameEvent.ON_LOAD_SCENE, start);

Related

Call to possibly undefined method dispatchEvent through a reference with static type GetColor

I'm writing a program using Main.as, that needs to listen to a function (getColor) in another class file (GetColor.as). I have the following in GetColor.as:
public class GetColor
{
public function getColor(event:MouseEvent):void
{
//doing stuff here
this.dispatchEvent(new Event("changeColor") );
}
}
and then in Main.as I have:
var getPicColor:GetColor = new GetColor();
getPicColor.addEventListener("changeColor",changeColorNow);
function changeColorNow(e:Event):void
{
//do stuff here
}
However, I am getting an error:
1061: Call to a possibly undefined method dispatchEvent through a reference
with static type GetColor.
What does this mean? I have nothing declared as static. Am I supposed to create an instance of dispatchEvent(), as opposed to using "this"?
You cannot dispatch events with a class that (implicitly) extends Object -> that's why you are getting there error -> where is "dispatchEvent()" method coming from? Where is it inherited from? (answer: it is not!)
Your GetColor class (horrible name there! :) ) must either extend a display object - which in your case it not really the correct solution, extend EventDispatcher or implement IEventDispatcher.
Then you can use the method dispatchEvent.

Union type in ActionScript?

Do you know if ActionScript support union type? For example, something like that:
function foo(x:ClassA Union classB) {
//x is classA or classB
//do something
}
Thanks in advance
Actionscript 3 does not support c++ style mixin class hierarchies.
As3 rather uses the Interface approach that is utilized in many object oriented languages.
An Interface generally is an abstract template of functionality allowing communication between objects which are unrelated in respect of class hierarchy.
such as:
public interface IBox{
function addContentToBox(contentName:String, content:*) Boolean;
function boxHasContent(contentName:String): Boolean;
function getContentFromBox(contentName:String): *;
}
When you define a class in as3, if you want it to implement IBox Interface you write
class YourClass extends anotherClass implements IBox {
(extends anotherClass is only needed if you are extending another class)
Now you have to write code for functions declared in IBox in YourClass.
Then what is the catch? Well, first of all
a = new YourClass(parameters etc);
if(a is YourClass)trace('YIPPE');
if(a is IBox)trace('YAY');
You have a trace of YIPPE YAY now.
(xxx is IBox) will be true for all instances of all classes implementing IBox.
You can pass any unrelated objects with classes implementing IBox to functions expecting IBox.
Please refer to Adobe as3 interface document for further information.
I hope this helps.
Closest you can get to that is by having a base class A and deriving two classes from it B and C. Then you can pass either B or C instances to the function foo.
class classA {}
class classB extends classA {}
class classC extends classA {}
function foo(x:ClassA)
{
if(x is classB)
trace("x is classB");
else if (x is classC)
trace("x is classC");
}
var c:ClassC = new ClassC();
foo(c);
Though I wouldn't suggest checking types of classes and executing code based on that, using an interface would probably help you out, but we would need to know what you are trying to do.

Override function in CS5 IDE -> Timeline -> Framescript

I have a baseclasse which implements an interface. I use this baseclass as my "template" ( read: Semantics, i'm not talking about Java/C++ Templates).
In my Flash CS5 IDE I want to override these interface methods.
Yes they are implemented in the base class, but trying to override them in framescript throws me( YES this might probably not be a clean design):
Symbol 'GameTest', Layer 'Layer 1', Frame 1, Line 1 1024:
Overriding a function that is not marked for override.
I don't exactly know in what scope framescripts work. And by framscript I just mean in the timeline frame 1.
in my base class:
public class MiniGameTemplate extends MovieClip implements IMiniGame
{
public function MiniGameTemplate()
{
}
public function update():void
{
}
}
In my Library object's first frame:
override function update():void
{
}
I'm using actionscript linkage to inherit my library object from the base class.
If I clear the framescript, it runs fine. No error.
When overriding a method, you must structure the overriding method exactly like the original. In this case you've missed the public access modifier statement.
Solution:
override public function update():void {
}

Undefined properties when implementing interface

Here's my class signature:
public class YouTubeControls extends Controls implements IControls
YouTubeControls has a public var foo. This code:
var controls:IControls = new YouTubeControls();
trace(controls.foo);
results in this error:
Access of possibly undefined property foo through a reference with static type IControls.
My application is going to have other "Control" classes, so casting controls (YouTubeControls(controls)) won't work. How can I access controls.foo?
Edit
If I can't do this without casting, how do I handle the problem of needing to know which class to cast it as?
trace(controls.foo); is the same as calling IControl(controls).foo since you controls variable is declared to be of type IControl. The problem is that you did not give the IControl interface a getter function foo. Note, properties are not allowed in interfaces, only methods. See the other answers here.
If foo is defined in YouTubeControls, you will not be able to access it through a reference to IControls. If you change your code to this, it will work:
var ytControls:YouTubeControls = new YouTubeControls();
trace(ytControls.foo);
var controls:IControls = ytControls;
However, you mentioned that other controls may also have a foo property; if that's the case, then you should define that property in IControls, not YouTubeControls.
I don't have access to Flash Builder at the moment, but I believe that you should be able to do use the 'as' operator to test if the object is one class or another.
if ((controls as YouTubeControls) != null) //controls IS a YouTubeControls
//because it didn't return null
trace((controls as YouTubeControls).foo);
else
...
The advantage to the 'as' operator is that it attempts to cast, but if it fails it returns null, while the other form of casting...
YouTubeControls(controls)
Will throw a runtime exception if controls cannot be cast as a YouTubeControls.
If you have several IControls you may want to extend this interface.
public interface IMyControl extends IControl
{
public function get foo():SomeType;
}
And then
public class YouTubeControls extends Controls implements IMyControl
in each of your controls class.

Friend methods/classes for AS3 packageless classes

Hi I'm wondering if I can have a packageless () AS3 class call a private method on the main class in the file. For example:
package demo
{
public class MyDemoClass
{
var helper:FriendlyHelperClass = new FriendlyHelperClass(this)
}
private function methodToCall():void
{
...
}
}
public class FriendlyHelperClass
{
public function FriendlyHelperClass(demo:MyDemoClass)
{
demo.methodToCall()
}
}
The call to methodToCall() from FriendlyHelperClass will fail as it is a private member of the MyDemoClass. Is there any way to call the methodToCall() method from the FriendlyHelperClass without extending MyDemoClass.
Basically I'm looking for inner class functionality that Java has or some sort of C++ style friend class.
Short answer : no.
You can never access a private member from outside a class in ActionScript. What you could do is use a namespace instead of a private scope. This would allow to give access to some members to selected classes. This is the closest of a friend class that you will get in AS3.
I'm afraid that is not possible, but if you make the class dynamic, then you can edit it while the program is running, and possibly add some useful functions to it, to access the private functions. I haven't tried it though.
Dynamic classes
Without testing the code, and knowing what your full problem. you can try passing the functions you need into the embedded class as a callback. e.g.,
helper.methodToCallCallback = this.methodToCall;
then inside FriendlyHelperClass:
this.methodToCallCallback();