Actionscript: call a superclass method from a subclass - actionscript-3

What I would like to do is to call a method from a superclass in a subclass. Specifically I want to be able to add the subclass as a child of the superclass but without physically having to type addChild in the superclass (but I will have to type it in the subclass). For now I'm just trying to call a method in the superclass that draws some text from a subclass.
Here is the MAIN class (the superclass)
package
{
import flash.display.*;
import flash.events.*;
import flash.text.*;
public class MAIN extends Sprite
{
public var SOMETEXT:TextField = new TextField();
public function MAIN()
{
new OBJECT_square().CREATE();
}
public function DRAWTEXT():void
{
SOMETEXT.text = "sometext";
addChild(SOMETEXT);
}
}
}
Here is the OBJECT_square class (the subclass)
package
{
import flash.display.*;
import flash.events.*;
public class OBJECT_square extends MAIN
{
public function CREATE():void
{
MAIN.DRAWTEXT();
}
}
}
The code doesn't compile, I get "Call to a possibly undefined method DRAWTEXT through a reference with a static type class".
I realize there are otherways to display text on the screen. I just need to learn how to call superclass methods.

Just call it regularly. When you have a class extend a base class, the class inherits all the base classes methods.
package
{
import flash.display.*;
import flash.events.*;
public class OBJECT_square extends MAIN
{
public function CREATE():void
{
DRAWTEXT();
}
}
}

Edited
My bad about suggesting static, I clearly didn't pay much attention to your code before answering. DRAWTEXT doesn't show up anything because your object has not beed added to the stage. You have to call addChild() to see your diplsay object.
As a side note, don't take this bad, buy you have been asking a lot of questions that show that you lack a basic understanding of how Flash and Actionscript works (and also you seem to be a bit too insistent on having it work the way you want).
It's always ok to ask questions here (as long as you keep them on-topic, which seems to be the case with your questions), but I think you would be better off first learning the basics from some good books, tutorials, etc.
These two posts contain links to good resources, I think you should check them out.
Resources for Learning ActionScript 3.0 as a Professional Programmer
https://stackoverflow.com/questions/168586/where-to-learn-actionscript-3-0
Also, what's with all these users with the same name? Right now I can see 9 users with the name 1101 here: https://stackoverflow.com/users/, and I think all of them are yours. One is enough. Really. You don't need to create a new user everytime you want to ask a question. Also, try to follow up the questions you've asked to give some feedback to the people that bothered answering (this will be much easier if you have just one user). And when you want to comment on some response, leave a comment instead of adding an answer.

Related

Error when overriding constructor of extended class

I found a quite strange problem while making two classes in AS3. Let's call them ParentClass and ChildClass. In order to make both of them you need a Sprite object, then the ParentClass makes it visible in the stage. ChildClass inherits the ParentClass, too.
ParentClass.as:
package myStudio.basic {
import flash.display.MovieClip;
import flash.display.Sprite;
public dynamic class ParentClass extends MovieClip {
public function ParentClass(mc:Sprite=null) {
addChild(mc);
}
}
}
ChildClass.as:
package myStudio.containers {
import myStudio.basic.ParentClass;
import flash.display.MovieClip;
import flash.display.Sprite;
public class ChildClass extends ParentClass {
public function ChildClass(mc:Sprite=null) {
addChild(mc);
}
}
}
Then, I write this code on Frame 1, Layer Actions of the FLA file:
var mc:MovieClip = new childMC;
var vig:ChildClass = new ChildClass(mc);
addChild(vig);
However, I got run-time error #2007:
TypeError: Error #2007: The value of the parameter child must not be null.
at flash.display::DisplayObjectContainer/addChild()
at myStudio.basic::ParentClass()
at myStudio.containers::ChildClass()
at myStudioComicAnimator_fla::MainTimeline/frame1()
I tried overriding the ChildClass constructor function, but it still doesn't work.
So here's my question: Is there another workaround to solve this problem?
The reason for that is that you are not calling super. You can check what's happening in the error stack (down to top):
you instantiate ChildClass, and you pass the previously created childMC to the constructor
ChildClass extends ParentClass, so when instantiated it always calls the constructor
the constructor of ParentClass tries to add something as a child
The problem is that you cannot add null as a child. But because the constructor is called internally, there is no param that is being passed to it. so mc variable is always null. But as we said - null cannot be added.
Use the super by yourself:
public function ChildClass(mc:Sprite=null) {
super(mc);
}
This way the ParentClass will get reference to the mc object and will be able to add it.
Another option is not to use addChild in the ParentClass, but only in ChildClass. Then it doesn't matter if you pass anything to super, or even if you are calling super at all.
Edit: I forgot to say that this is not a bug, but a standard behavior and works exactly like it should work. The reason for this is that each class can have a whole different override of the constructor. It can take more or less parameters, so the chain for calling parent's constructor is your job to handle.

Call custom method as Display Object AS3

I have a class which extends MovieClip. This class has an update() function which needs to be called every new frame with the deltaTime in the arguments. This works if the class has been declared but not if it has just been added to the display list.
Code in the main class:
package packageFoo{
import flash.display.MovieClip;
import packageFoo.customMovieclip;
public class Main extends MovieClip{
public function Main():void{
var testMc:customMovieClip = new customMovieClip();
addChild(testMc);
testMc.update(dt);
}
}
}
This outputs the correct values where as if I just added it without referencing it:
package packageFoo{
import flash.display.MovieClip;
import packageFoo.customMovieclip;
public class Main extends MovieClip{
public function Main():void{
addChild(new customMovieclip());
this.getChildAt(0).update(dt);
}
}
}
This makes the compile time error: 1061: Call to a possibly undefined method update through a reference with static type flash.display:DisplayObject.
I can't really reference the 'customMovieclip's because I am wanting multiple ones.
It looks like this.getChildAt(0) is not customMovieClip. This can arise if your Main has pre-places components at design time. To check, do trace(this.numChildren) as the first line of Main() constructor. And also, to address any subclass methods properly, you need to typecast your DisplayObject returned by getChildAt() to a proper type.
(this.getChildAt(0) as customMovieClip).update(dt);
Still, using a class-wide variable is better if you want to address that custom MC in more than one function of main class.
If you're trying to avoid a reference to the custom class in the document class, you can call it like this:
this.getChildAt(0)["update"](dt);

AS3, Flash - Call a function in a class?

I am trying to call a function which is set inside a class..
How can I call that?
Here is my source, and I would like to call 'processLogin' from outside this class.
Link to source: http://pastebin.com/aFygyXKZ
You can create a new instance of your class main.
Try
var m:main = new main();
m.processLogin();
Also, AS3 best practices state that classes should begin with an Uppercase letter.
You also should extend Sprite instead of MovieClip for DisplayObject classes that do not need timeline functionality.
If you know you are only going to have one instance of the class main in your application, what you can do is:
Implement class main as a singleton class, in which case you
can access the processLogin method using
main.getInstance().processLogin or
Just add a public static
variable to your main class containing the instance of your main
class. In this instance your code would look something like:
package actions {
import flash.display.MovieClip;
import flash.events.*;
import flash.net.*;
import flash.text.*;
public static var instance:main;
public function main(){
instance = this;
}
//The rest of your main class code...
}
That way, you can access your processLogin function using main.instance.processLogin().
However, if your application is set to possibly have more than one instance of your main class, then the best approach would be to instantiate main and use that instance, as f-a suggested.

AS3: Compiler bug with inner classes and interfaces?

For some irrelevant reasons I need a class:
that inherits (directly or not) from MovieClip.
that implements a particular interface (let's assume here that this interface is empty since it does not change anything to the issue).
and whose .as file declares internal classes.
The following code sums this up:
package {
import flash.display.MovieClip;
public class MyClass extends MovieClip implements EmptyInterface { }
}
class MyInnerClass { }
The problem with that code above is that it will not always compile. As soon as I use MyClass as Linkage for one of my library's item the compiler complains about MyClass not being a subclass of MovieClip. On the other hand, everything works great if I instantiate it manually and add it to the stage.
It looks like the interface and the inner class are somehow mutually exclusive in that very particular case. Indeed, if I remove the inner class I do not have that error anymore:
package {
import flash.display.MovieClip;
public class MyClass extends MovieClip implements EmptyInterface { }
}
Same thing when I remove the implemented interface but keep the inner class:
package {
import flash.display.MovieClip;
public class MyClass extends MovieClip { }
}
class MyInnerClass { }
Note that I've only tested this in Flash CS5.
I say it is a bug of compiler.
I have tested and found that private class must extend any class that is not Object. Instead of extending class it can also implement any interface.
This works same even if I put classes into deeper package.
I have tested this with Flash CS6.
If I'm reading you right, you want a public class to extend an internal class? - There is nothing that prevents you from doing this, so long as you declare your internal class as it's own packaged file.
According to the documentation:
[dynamic] [public | internal] [final] class className [ extends superClass ] [ implements interfaceName[, interfaceName... ] ] {
// class definition here
}
If it's the interface that is giving you grief, have you declared it in a separate file as well - that you would import? As eluded to in the comments, the namespace scoping is important so that the compiler understands what the escalating priority is.
Eg:
package my.example {
public interface EmptyInterface
{
}
}
So that:
package {
import flash.display.MovieClip;
import my.example.EmptyInterface;
public class MyClass extends MovieClip implements EmptyInterface { }
}
If this doesn't fix it I have another idea but try this first.
Click file
Click publish setting
Click on settings button
Uncheck Automatically declare stage instances
Click OK

Reading all classes under a package or reading classes with same Metadata in Actionscript 3.0

I am doing an Actionscript 3.0 project which involves introspection. I am wondering if there is a way to get all the classes within a given package structure.
For e.g. Say there are three as3 classes:
com.example.test.classOne
com.example.test.classTwo
com.example.test.classThree
I want to be able to say
getClassesUnderPackageName("com.example.test");
and get back
"com.example.test::classOne"
"com.example.test::classTwo"
"com.example.test::classThree".
Is there a way to do that?
If this is not possible, is there a way to read classes which have the same metadata?
E.g. If all the mentioned classes have the same metadata [MetadataName(type="example")] defined, is there a way to say
getClassesWithSameMetadata("MetadataName");
and get back
"com.example.test::classOne"
"com.example.test::classTwo"
"com.example.test::classThree".
Thank you.
you can use flash.utils.describeType to return XML data containing this information. it works differently on base classes, like flash.display.Sprite, but for custom classes/directories, you can write something like this:
package branchA.branchB.branchC
{
//Imports
import flash.utils.describeType;
//Class
public class Test
{
//Constructor
public function Test()
{
trace(describeType(this).#name);
}
}
}
//OUTPUT: branchA.branchB.branchC::Test
if you wanted to return the base class, you could write something like this:
package
{
//Imports
import flash.display.Sprite;
import flash.utils.describeType;
//Class
public class Test extends Sprite
{
//Constructor
public function Test()
{
trace(describeType(this).#base);
}
}
}
//OUTPUT: flash.display::Sprite
there is lots of other useful information you can get by parsing the returned XML data of describeType.
Update:
class objects do not need to have been instantiated first in order to retrieve their information via describeType(). you could build a public static function (or whatever) which accepts an array of your class objects and returns an array of strings containing the required describeType data.
something like this:
package
{
import flash.utils.describeType;
final public class Describe
{
public static function packageNames(classObjects:Array):Vector.<String>
{
var names:Vector.<String> = new Vector.<String>();
for each (var classObject in classObjects)
names.push(describeType(classObject.#name.toString()));
return names;
}
}
}
then from anywhere in your program, you can pass an array of all the classes like this:
var names:Vector.<String> = Describe.packageNames(new Array(classOne, classTwo, classThree));
trace(names);
//Output:
//com.example.test::classOne
//com.example.test::classTwo
//com.example.test::classThree
There's no inbuilt mechanism for finding classes without already knowing the class name. :(
However if you load in a SWF as a ByteArray then it's possible to iterate through the classes in it.
This might be overkill for what you want.
http://www.bytearray.org/?p=175
Take a look at AS3 Commons Bytecode. It allows you to do Bytecode based reflection. You can list all classes (you'll need to filter those if you just want a particular package), list classes with certain metadata or classes that implement a certain interface.