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.
Related
As the question states, I want to know how I can make a function in a class that other classes can access, but subclasses cannot. I have a class that has some public getters and setters that I want my document class to have access to call, but I don't want the subclass to have these functions because they'd be useless on the subclass.
For example
public class SomeClass
{
public function SomeClass() {}
public function notInherited():void { trace("Not inherited"; }
}
public class OtherClass extends SomeClass
{
public function OtherClass()
{
notInherited(); //Want this to return an error
}
}
public class HasAccess
{
public function HasAccess()
{
notInherited(); //Not inherited
}
}
I know this probably has something to do with custom namespaces, but after searching up about them I still don't really have much understanding of how they work. That's about it; thanks for reading.
You can't do this quite in the general terms you've asked, but you can do this if you put your document class and your other class in the same package and use internal instead of public, and you put your sub-class in a different package. The internal keyword limits access to classes in the same package.
Example (notice the package statements):
package main {
public class Main extends MovieClip {
public function Main() {
var stuff:Stuff = new Stuff();
stuff.doStuff();
}
}
}
package main {
public class Stuff {
internal function doStuff():void { }
}
}
package other {
public class OtherStuff extends Stuff {
public function OtherStuff() {
// no access to this.doStuff()
}
}
}
As for using a namespace, this can be a good option to make the intent of your code more clear, but it doesn't actually limit access in any new way, it just requires access to be more deliberate: while the namespace does hide visibility of the API to anyone who doesn't use the namespace, anyone can use the namespace and have access to the API without any additional limits (ie public, internal and protected).
Still, this may be all you are after. Here's an example which uses a public namespace and no packages:
// my_stuff.as
package {
public namespace my_stuff;
}
// Stuff.as
package {
public class Stuff {
my_stuff function doStuff():void { }
}
}
// Main.as
package {
import flash.display.MovieClip;
public class Main extends MovieClip {
public function Main() {
use namespace my_stuff; // you can put this above the class to give the entire class access to the namespace
var stuff:Stuff = new Stuff();
stuff.doStuff();
}
}
}
// OtherStuff.as
package {
public class OtherStuff extends Stuff {
public function OtherStuff() {
this.doStuff(); // not allowed
this.my_stuff::doStuff(); // allowed
// also allowed
use namespace my_stuff;
this.doStuff();
}
}
}
(Note that if your namespace is in a package, ex package stuff { public namespace my_stuff }, you must import the namespace just like a class, for example: import stuff.my_stuff)
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();
}
}
}
I have some classes that implement an interface, but also extend the Sprite class:
package {
public interface IState {
function addMonster():void;
}
}
package {
public class Fuzzy extends Sprite implements IState {
public function addMonster():void {
}
}
}
package {
public class LizardSkin extends Sprite implements IState {
public function addMonster():void {
}
}
}
// Document class
package {
public class Main extends MovieClip {
private var state:IState;
public function Main():void {
state = new Fuzzy();
addChild(state);
}
}
}
When I try to addChild(state) I keep getting an error message 1067: Implicit coercion of a value of type IState to an unrelated type flash.display:DisplayObject.
Now I know I've seen examples where a class extends MovieClip / Sprite and implements an interface...what can I do to make it so I can add "state" to the stage but also implement the methods I want??
A simple cast should do it most of the time:
addChild(state as DisplayObject);
The compiler raises that error otherwise because it doesn't assume IState is always implemented by something that is a DisplayObject, but if you can guarantee that condition you can always cast.
What I do in situations like this is use an IDisplayable interface, that looks like this:
public interface IDisplayable
{
function get displayObject():DisplayObject;
}
and its implementation in a Sprite or MovieClip simply looks like this:
public function get displayObject():DisplayObject
{
return this;
}
Your IState objects could then be added to the stage using addChild(state.displayObject);, when your IState interface extends IDisplayable.
Is there any non-hacky way to determine wether a class' superclass implements a particular interface?
For example, assume I've got:
class A extends EventDispatcher implements StuffHolder {
protected function get myStuff():Stuff { ... };
public function getStuff():Array {
if (super is StuffHolder) // <<< this doesn't work
return super['getStuff']().concat([myStuf]);
return [myStuff];
}
class B extends A {
override protected function get myStuff():Stuff { ... };
}
How could I perform that super is StuffHolder test in a way that, well, works? In this case, it always returns true.
In this case you might have to define StuffHolder (and have it extend EventDispatcher) as a class and have getStuff as a public/protected function. You could then overload the getStuff function in class A, but not in class B.
package {
public class StuffHolder extends EventDispatcher {
function StuffHolder() {
}
protected function getStuff():Array{
return ["Default"];
}
}
}
package {
public class A extends StuffHolder {
function A {
super();
}
protected override function getStuff():Array {
return ["A"];
}
}
}
package {
public class B extends StuffHolder {
function B {
super();
}
}
}
I don't have the full picture to figure out why you'd need that kind of (weird and possibly broken) inheritance, but could you rephrase it to if (this is actually an A instance)?
If so, you could go with...
import flash.utils.getQualifiedClassName;
if (getQualifiedClassName(this) == 'A')
The thing is, the is operator should be used on object instances. And it works all the way up to object -- I mean, A is B is true for every A ancestor or interface implementation.
I think you could come up with a better structure for your classes, though.
This isn't that pretty.
I could do something involving introspection, getting the current class, finding its parent class, then checking to see if that implements the StuffHolder interface… But that seems pretty ugly :(
How can I make an abstract class in AS3 nicely?
I've tried this:
public class AnAbstractClass
{
public function toBeImplemented():void
{
throw new NotImplementedError(); // I've created this error
}
}
public class AnConcreteClass extends AnAbstractClass
{
override public function toBeImplemented():void
{
// implementation...
}
}
But.. I don't like this way. And doesn't have compile time errors.
abstract classes are not supported by actionscript 3. see http://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/
the above reference also provides a kind of hackish workaround to create abstract classes in as3.
Edit
also see http://www.kirupa.com/forum/showpost.php?s=a765fcf791afe46c5cf4c26509925cf7&p=1892533&postcount=70
Edit 2 (In response to comment)
Unfortunately, you're stuck with the runtime error. One alternative would be to have a protected constructor.... except as3 doesn't allow that either. See http://www.berniecode.com/blog/2007/11/28/proper-private-constructors-for-actionscript-30/ and http://gorillajawn.com/wordpress/2007/05/21/actionscript-3-%E2%80%93-no-private-constructor/.
You may Also find these useful: http://www.as3dp.com/category/abstract-classes/ and, in particular, http://www.as3dp.com/2009/04/07/design-pattern-principles-for-actionscript-30-the-dependency-inversion-principle/
package
{
import flash.errors.IllegalOperationError;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import flash.utils.getQualifiedSuperclassName;
public class AbstractClass
{
public function AbstractClass()
{
inspectAbstract();
}
private function inspectAbstract():void
{
var className : String = getQualifiedClassName(this);
if (getDefinitionByName(className) == AbstractClass )
{
throw new ArgumentError(
getQualifiedClassName(this) + "Class can not be instantiated.");
}
}
public function foo():void
{
throw new IllegalOperationError("Must override Concreate Class");
}
}
}
package
{
public class ConcreteClass extends AbstractClass
{
public function ConcreteClass()
{
super();
}
override public function foo() : void
{
trace("Implemented");
}
}
}
In AS3 would just use interfaces to make sure all functions are implemented at compile time.
I know it different but does the trick for an example such as the one above.
As long as they don't permit non-public constructors in actionscript, you'd have to rely on run time errors for abstract classes and singletons.