So i have two Class's Class A and Class B.
I have a function that i wish to use on Class A but my flash fla file is linked to Class B
So I have done the following:
Class A - the function
public function Fb_Checks()
{
// constructor code
load_top_bar();
}
Class B - import
import ClassA;
then if i try to call the function in Class A from Class B:
Fb_Checks();
I get the following error:
Call to a possibly undefined method Fb_Checks.
Is there something more i should be doing to get this to work?
You need to get more info about the OOP. How it is working then it will be easier to understand concepts.
For now simple explanation: We have ClassA, ClassB and ClassC:
ClassA
{
var value:ClassB;
public function ClassA ()
{
// each variable needs to initialize unless it is the ClassC, see below
// Only after that you will be able to reach the public properties
// of the class.
value = new ClassB();
value.calculate();
}
}
ClassB
{
var value:Number;
public function ClassB ()
{
}
public function calculate():void
{
// these must be statis
ClassC.sum(150, 450);
}
}
ClassC
{
// if the function is static, then you can call it without initializing
// the class
static public function sum(value1:Number, value2:Number):Number
{
return value1 + value2;
}
}
You'll have to make an instance of ClassA before you can call its public functions.
package
{
import ClassA;
public class ClassB
{
public function ClassB()
{
var instanceOfA:ClassA = new ClassA();
instanceOfA.Fb_Checks();
}
}
}
If you want to make it work like your example you should extend your ClassB with the ClassA. In that case it's public and protected functions are available in ClassB as well.
package
{
import ClassA;
public class ClassB extends ClassA
{
public function ClassB()
{
Fb_Checks();
}
}
}
Related
I'm new to Flex. I have some doubt regarding Interface in Flex. As we know AS3 is also an Object Oriented Language.
Questions are :
1.if class A extends Class B. Then Class A can't implements interface C. Why ?
The class which don't extends other class can implement the interface. What is the reason behind that ?
why we can't give access specifier to the functions declaration in Flex Interface ?
Why can't we write like
class A extends class B implements C
Updates Of My Question with Code
Interface Part ->
package
{
public interface InterfaceTesting
{
function foo():void;
}
}
Class A ->
package
{
import mx.controls.Alert;
public class A
{
public function test():void
{
trace("control is in Top Class")
Alert.show("control is in Top Class");
}
}
}
Class B ->
package
{
import mx.controls.Alert;
import mx.messaging.channels.StreamingAMFChannel;
import mx.states.OverrideBase;
public class B extends A implements InterfaceTesting
{
override public function test():void
{
Alert.show("We are in Second Class");
}
public function foo():void
{
Alert.show("This is Interface Implementation");
}
}
}
I'm getting an Error in class B. which is 1024- Overriding a function which is not marked for override.
Please Guide me.
I'm not entirely sure what you're asking, but what you're describing should be possible.
A valid example:
ClassA.as
package {
public class ClassA extends ClassB implements InterfaceC {
public function ClassA() {
}
public function bar():void {
}
}
}
ClassB.as
package {
public class ClassB {
public function ClassB() {
}
public function foo():void {
}
}
}
InterfaceC.as
package {
public interface InterfaceC {
function foo():void; // Will be inherited from ClassB
function bar():void; // Is defined in ClassA
}
}
Edit: Regarding your third question:
To comply with an interface, the methods defined in the interface needs to be either public or internal. This is because an interface is useful only for declaring what methods are available publicly.
If your class implements InterfaceC (above) and contains the function foo() but has declared it private - it cannot be reached externally and hence won't comply with the interface.
I have a parent class called 'main.as'. I am trying to get the child class to call main's function. They both reside in the same folder.
// main.as //
package {
public class main extends MovieClip {
public function main() {
var child:child_mc = new child_mc(this);
}
public function callFunction():void {
trace("Done it");
}
}
}
.
// child.as //
package {
import main;
public class child extends MovieClip {
private var main:MovieClip = new MovieClip();
public function child(main:MovieClip):void {
this.main = main;
main.callFunction();
}
}
}
This is the error I've been getting:
TypeError: Error #1006: callFunction is not a function.
so I tried doing a trace like this
trace(main.callFunction);
and it says undefined. Can someone tell me what I am missing. I get this feeling its a very basic thing that I have overlooked!
Your "child" package is defined as "main". I'm not even sure how it complied, let alone run to the point of showing the error message you got.
I believe the code below should do what you expected.
(I also took the liberty to rename the classes to use CamelCase (with initial caps) to adhere to best practices and to be easier to distinguish from variable names.)
Main.as
package {
public class Main extends MovieClip {
public function Main() {
var child:ChildMC = new ChildMC();
child.main = this;
}
public function callFunction():void {
trace("Done it");
}
}
}
EDIT: I just saw your comment that points out that child_mc is a MovieClip in the Library. I guess then that the child class is set as the Base Class of the child_mc?
If so, you cannot pass properties through the instantiator, you need to find another way to pass along the instance of the Main class to the Child class.
One way would be to add a setter, like the following:
Child.as (Base Class for ChildMC)
package {
public class Child extends MovieClip {
private var _main:Main;
public function Child() {
}
public function set main(main:Main):void {
this._main = main;
this._main.callFunction();
}
}
}
How do I do this?
public class SuperClass extends MovieClip {
public static var test:String = 'Hello world';
}
public class SubClass extends SuperClass {
public function SubClass() {
var unit = new Unit();
addChild(Unit);
}
}
public class Unit extends MovieClip {
public function Unit() {
//Get variable:test from SuperClass??
trace(SubClass.test); //Error
}
}
Hope you understand what I want to do?
Want to get the variable 'test' from the SuperClass in my new Unit added in SubClass.
Thanks!
In this case your class named SubClass uses the Unit class through composition, not inheritance. As such the Unit class knows nothing about SubClass or SuperClass or any of their properties like the test property.
You can, however, pass a value into the Unit class through it's constructor (or just set a value directly onto a property of the Unit class):
(showing the last two classes only)
public class SubClass extends SuperClass {
public function SubClass() {
var unit = new Unit(test);
addChild(Unit);
}
}
public class Unit extends MovieClip {
private var test:String;
public function Unit(test:String) {
this.test = test;
}
}
[Edit]
Since your Unit class needs to access many properties of SubClass (and/or SuperClass), you might want to just pass an instance of SubClass to Unit:
public class SubClass extends SuperClass {
public function SubClass() {
var unit = new Unit(this);
addChild(Unit);
}
}
public class Unit extends MovieClip {
private var subClass:SubClass;
public function Unit(subClass:SubClass) {
this.subClass = subClass;
trace(subClass.text);
}
}
How you actually solve this depends on your use case. But there is no fundamental shortcut to do what you are asking.
I am a little confused by this concept.
If I override a public function in a base class, I would have thought that this override function is called and the original is ignored? though this doesn't seem to be the case...
public class AbstractScreen extends Sprite
{
public function AbstractScreen()
{
}
public function updateLanguage():void
{
trace("WARNING: need to override public function updateLanguage()");
}
}
public class Start extends AbstractScreen
{
override public function updateLanguage():void
{
title.text = _model.language.start
title.setTextFormat(titleFormat);
}
}
public class ViewManager extends Sprite
{
private var _model:Model;
private var _screens:Array;
public function ViewManager(model:Model)
{
_model = model;
_model.addEventListener(AppEvent.INIT_VIEW, initViews);
_model.addEventListener(AppEvent.UPDATE_VIEW, updateView);
_model.addEventListener(AppEvent.CHANGED_LANGUAGE, changeLanguage);
}
private function initViews(e:AppEvent):void
{
trace("View Manager: initViews");
_screens = new Array(new Start(_model), new TakePhoto(_model));
dispatchEvent(new ViewEvent(ViewEvent.VIEW_READY));
}
private function changeLanguage(e:AppEvent):void
{
for each (var screen:AbstractScreen in _screens)
{
screen.updateLanguage();
}
}
}
If my model dispatches a CHANGED_LANGUAGE event, the text in the views gets updated, But I also get a trace of "WARNING: need to override public function updateLanguage()" What could I be doing wrong?
You are right, this should not call the base class function. Are you sure there is no call to
super.initLanguage()
within your override?
Most IDE's add this call in the function body automatically, if they create an override for you.
EDIT
From your edit I see your are iterating over two objects of the types Start and TakePhoto. I assume TakePhoto is also derived from AbstractScreen and the trace may be comming from this one.
Also I suggest to use the abstract base class in your iteration.
for each (var screen:AbstractScreen in _screens)
{
screen.updateLanguage();
}
Suppose in document class
public class Test extends MovieClip
{
public function Test()
{
var object1:ClassA = new ClassA();
//addChild(object1);
object1.accessRoot();
}
}
public class A extends MovieClip
{
public function accessRoot()
{
var mc : MovieClip = root as MovieClip;
mc.box.visible = false;
}
}
Now box is placed at stage. but when Class A is added to Test Class, it works and when object of Class A is not added in Test constructor, root becomes in-accessible. Is there any way that objects not on display-list can access root or display-list objects??
I would not recommend having your classes fiddle around with root or stage, it's way better to dispatch events and have the proper encapsulation.
Hacky way:
public class A extends MovieClip
{
private var _root:MovieClip;
public function A(root:MovieClip)
{
_root = root;
}
public function accessRoot()
{
_root.box.visible = false;
}
}
Proper way:
public class A extends MovieClip
{
public static const ACCESS_ROOT:String = "access_root";
public function accessRoot()
{
dispatchEvent(new Event(ACCESS_ROOT));
}
}
// in your document class
var myA:A = new A();
myA.addEventListener(A.ACCESS_ROOT, handleAccessRoot);
public function handleAccessRoot(e:Event):void{
box.visible = false;
}
I normally create a sort of base class that holds a reference to the document class - or "main" class. Anything that I create from here that should need reference to anything defined in Main would extend Element. Example:
The Main class (or document class):
public class Main extends MovieClip
{
/**
* Constructor
*/
public function Main()
{
var obj:MyElement = new MyElement();
obj.main = this;
// stage will be outputted
}
}
Element - which stores reference to the main class.
It also contains an init() function which I generally use in place of a constructor by overriding it.
public class Element extends MovieClip
{
private var _main:Test;
public function set main(m:Main):void
{
_main = m;
init();
}
/**
* Called when _main is defined
*/
protected function init():void
{
// override me
}
public function get main():Main{ return _main; }
}
And here's how you would use Element as a base class for your classes:
public class ClassA extends Element
{
/**
* Override init rather than using a constructor
*/
override protected function init():void
{
trace(main.stage);
}
}
The only thing really to note is that you of course have to set the _main property whenever you create an object. (as shown on line 9 of Main).