Union type in ActionScript? - actionscript-3

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.

Related

Run a 'constructor' or function, after class fields initialized, in a sane way?

I'd like to use ES6 public class fields:
class Superclass {
constructor() {
// would like to write modular code that applies to all
// subclasses here, or similarly somewhere in Superclass
this.example++; // does NOT WORK (not intialized)
//e.g. doStuffWith(this.fieldTemplates)
}
}
class Subclass extends Superclass {
example = 0
static fieldTemplates = [
Foo,
function() {this.example++},
etc
]
}
Problem:
ES6 public fields are NOT initialized before the constructors, only before the current constructor. For example, when calling super(), any child field will not yet have been defined, like this.example will not yet exist. Static fields will have already been defined. So for example if one were to execute the code function(){this.example++} with .bind as appropriate, called from the superclass constructor, it would fail.
Workaround:
One workaround would be to put all initialization logic after all ES6 public classes have been properly initialized. For example:
class Subclass extends Superclass {
example = 0
lateConstructor = (function(){
this.example++; // works fine
}).bind(this)()
}
What's the solution?
However, this would involve rewriting every single class. I would like something like this by just defining it in the Superclass.constructor, something magic like Object.defineProperty(this, 'lateConstructor', {some magic}) (Object.defineProperty is allegedly internally how es6 static fields are defined, but I see no such explanation how to achieve this programatically in say the mozilla docs; after using Object.getOwnPropertyDescriptor to inspect my above immediately-.binded-and-evaluated cludge I'm inclined to believe there is no way to define a property descriptor as a thunk; the definition is probably executed after returning from super(), that is probably immediately evaluated and assigned to the class like let exampleValue = eval(...); Object.defineProperty(..{value:exampleValue})). Alternatively I could do something horrible like do setTimeout(this.lateConstructor,0) in the Superclass.constructor but that would break many things and not compose well.
I could perhaps try to just use a hierarchy of Objects everywhere instead, but is there some way to implement some global logic for all subclasses in the parent class? Besides making everything lazy with getters? Thanks for any insight.
References:
Run additional action after constructor -- (problems: this requires wrapping all subclasses)
Can I create a thunk to run after the constructor?
No, that is not possible.
How to run code after class fields are initialized, in a sane way?
Put the code in the constructor of the class that defines those fields.
Is there some way to implement some global logic for all subclasses in the parent class?
Yes: define a method. The subclass can call it from its constructor.
Just thought of a workaround (that is hierarchically composable). To answer my own question, in a somewhat unfulfilling way (people should feel free to post better solutions):
// The following illustrates a way to ensure all public class fields have been defined and initialized
// prior to running 'constructor' code. This is achieved by never calling new directly, but instead just
// running Someclass.make(...). All constructor code is instead written in an init(...) function.
class Superclass {
init(opts) { // 'constructor'
this.toRun(); // custom constructor logic example
}
static make() { // the magic that makes everything work
var R = new this();
R.init(...arguments);
return R;
}
}
class Subclass extends Superclass {
subclassValue = 0 // custom public class field example
init(toAdd, opts) { // 'constructor'
// custom constructor logic example
this.subclassValue += toAdd; // may use THIS before super.init
super.init(opts);
// may do stuff afterwards
}
toRun() { // custom public class method example
console.log('.subclassValue = ', this.subclassValue);
}
}
Demo:
> var obj = Subclass.make(1, {});
.subclassValue = 1
> console.log(obj);
Subclass {
subclassValue: 1
__proto__: Superclass
}

Robotlegs wiring up dependencies that belong to a base class

I'm using robot legs, I've got a bunch of ServiceResponses that extends a base class and have a dependency on a Parser, IParser. I need to wire in a parser specific to the subclass. Here's an example:
ModuleConfigResponse extends SimpleServiceResponse and implements IServiceResponse.
The initial part is easy to wire in the context, here's an example:
injector.mapClass(IServiceResponse, ModuleConfigResponse);
injector.mapClass(IServiceResponse, SimpleServiceResponse, "roomconfig");
..etc
Each Response uses a parser that is used by the baseclass:
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
injector.mapValue(IParser, RoomConfigParser, "roomconfig");
The question is how to tie these together. The base class could have:
[Inject]
public var parser : IParser
But I can't define the type ahead of time. Im wondering if there a nice way of wiring this in the context. For the moment I've decided to wire this up by instanciating responses in a ResponseFactory instead so that I pay pass the parser manually in the constructor.
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
I realised that not everything can be mapped in the context, RL trapped me into this way of thinking. But I've realised that its far better to map a factory to produce these objects which have very specific dependencies, than littler the codebase with marker interfaces or strings :)
one solution is to have the following in your base class:
protected var _parser : IParser
Then for instance in ModuleConfigResponse
[Inject(name='moduleconfig')]
public function set parser( value : IParser ) : void{
_parser = value;
}
But TBH, using named injections is STRONGLY discouraged, you might as well use a marker interface:
public interface IModuleConfigParser extends IParser{}
the base class stays the same, but ModuleConfigResponse would then use:
[Inject]
public function set parser( value : IModuleConfigParser ) : void{
_parser = value;
}

OOP Proper use of interfaces in AS3

I'm designing a framework and in the process I have come across an interesting but most likely basic problem. I have a base class called CoreEngine and two other classes that extend it: CoreEngine1 and CoreEngine2. I created an interface that each of these classes would implement to increase the flexibility of my project. However, I have a problem... The definition of my methods in the interface do not match the definition in each inherited class! Each class must implement the following method:
function get avatar():AvatarBase;
The problem is that CoreEngine1 and CoreEngine2 expect a different type of avatar:
CoreEngine1
function get avatar():AvatarScaling
CoreEngine2
function get avatar():AvatarPlatform
As you can see, the return type for avatar in CoreEngine1 and CoreEngine2 do NOT match the type as specified in the interface. I was hoping that since both AvatarScaling and AvatarPlatform inherit AvatarBase that I wouldn't have a problem compiling. However, this is not the case. According to Adobe's documentation, the types MUST match the interface. I am trying to follow one of the core concepts of object oriented programming to extend the flexibility of my framework: "Program to an interface rather than an implementation". The first thing that comes to my mind is that the return type of the accessor method should be of an interface type (Maybe I just answered my own question).
I'm certain this is a common problem others have run into before. Architecturally, what do you think is the best way to solve this problem? Thanks in advance!
Regards,
Will
This is a limitation of how interfaces work and are declared.
If there's inheritance that can happen with the return types, as you've described with AvatarBase and subclasses, then I think the right approach is to make the return type the lowest common denominator and just handle the resulting object on the other end. So, if you're dealing with a CoreEngine1 object, you know you can cast the result from AvatarBase to AvatarScaling. Alternately, if you don't know the object type that you are calling get avatar() on, then you can type check the returned value. The type check would then only be needed if you're looking to call a method that exists on AvatarScaling but not on AvatarBase. I don't think returning an interface type will buy you much in this case because the only things that interface can implement would be things that all forms of Avatar share, which wouldn't be any different than methods in AvatarBase.
Like HotN and Dinko mentioned, it would be best to allow get avatar() to return AvatarBase allways and then cast the returned object as the concrete subclass.
Using Dinko's example:
public /* abstract */ class CoreEngine
{
public /* abstract */ function get avatar():AvatarBase {}
}
public function CoreEngine1 extends CoreEngine
{
override public function get avatar():AvatarBase { return new AvatarScaling(); }
}
public function CoreEngine2 extends CoreEngine
{
override public function get avatar():AvatarBase { return new AvatarPlatform(); }
}
public /* abstract */ class AvatarBase {}
public class AvatarScaling extends AvatarBase
{
public function someAvatarScalingMethod():void {}
}
public class AvatarPlatform extends AvatarBase
{
public function someAvatarPlatformMethod():void {}
}
To use a method from AvatarScaling, cast the returned object:
var c1:CoreEngine1 = new CoreEngine1();
var avatarScaling:AvatarScaling = AvatarScaling(c1.avatar());
avatarScaling.someAvatarScalingMethod();
hth
I think you answered your own question... the return type would still be AvatarBase, you need to follow the signature that you specified in the interface... but you can technically return ANY descendent of AvatarBase in that function. So doing something like
return new AvatarScaling();
in CoreEngine1 would be perfectly acceptable.
Of course in your calling function you will get back an AvatarBase instance, and you will have to know what this is in order to cast to a specific subclass.
CoreEngine1 ce1 = new CoreEngine1();
AvatarScaling avatar = ce1.avatar() as AvatarScaling;

actionscript-3: refactor interface inheritance to get rid of ambiguous reference error

imagine there are two interfaces arranged via composite pattern, one of them has a dispose method among other methods:
interface IComponent extends ILeaf {
...
function dispose() : void;
}
interface ILeaf {
...
}
some implementations have some more things in common (say an id) so there are two more interfaces:
interface ICommonLeaf extends ILeaf {
function get id() : String;
}
interface ICommonComponent extends ICommonLeaf, IComponent {
}
so far so good. but there is another interface which also has a dispose method:
interface ISomething {
...
function dispose() : void;
}
and ISomething is inherited by ICommonLeaf:
interface ICommonLeaf extends ILeaf, ISomething {
function get id() : String;
}
As soon as the dispose method is invoked on an instance which implements the ICommonComponent interface, the compiler fails with an ambiguous reference error because ISomething has a method called dispose and ILeaf also has a dispose method, both living in different interfaces (IComponent, ISomething) within the inheritace tree of ICommonComponent.
I wonder how to deal with the situation if
the IComponent, the ILeaf and the ISomething can't change.
the composite structure must also work for for the ICommonLeaf & ICommonComponent
implementations and the ICommonLeaf & ICommonComponent must conform to the ISomething type.
this might be an actionscript-3 specific issue. i haven't tested how other languages (for instance java) handle stuff like this.
You are searching for a solution to the Diamond Problem. C# has an approach to this but basically I would factor the method "dispose" out of your interfaces and create a new "IDisposable".
If the same name like "id" is used twice, it looks like a problem in your code with an ambiguous name. We started to add prefixes to properties and methods. Imagine you have a property "name" that belongs to two different things. Like the "displayName" and the "uniqueName".
This also helps with auto completion. If a DisplayObject is an ILayoutObject and yout type displayObject.layout you get everything layout releated.
It seems casting solves the ambiguity even though it's far from neat.
class SomeComponent implements ICommonComponent {}
var c : ICommonComponent = new SomeComponent();
trace(ISomething(c).dispose()); //compiles
trace(IComponent(c).dispose()); //compiles
trace(c.dispose()); //fails
As far as I'm aware, there's no neat way to deal with this problem in Actionscript.
The only thing I can think of is refactoring your interfaces to avoid name clashes, which, admitedly, it's not always possible.
Don't know about Java, but C# has a way to handle this through explicit interface implementation.

Language Agnostic Basic Programming Question

This is very basic question from programming point of view but as I am in learning phase, I thought I would better ask this question rather than having a misunderstanding or narrow knowledge about the topic.
So do excuse me if somehow I mess it up.
Question:
Let's say I have class A,B,C and D now class A has some piece of code which I need to have in class B,C and D so I am extending class A in class B, class C, and class D
Now how can I access the function of class A in other classes, do I need to create an object of class A and than access the function of class A or as am extending A in other classes than I can internally call the function using this parameter.
If possible I would really appreciate if someone can explain this concept with code sample explaining how the logic flows.
Note
Example in Java, PHP and .Net would be appreciated.
Let's forget about C and D because they are the same as B. If class B extends class A, then objects of type B are also objects of type A. Whenever you create an object of type B you are also creating an object of type A. It should have access to all of the methods and data in A (except those marked as private, if your language supports access modifiers) and they can be referred to directly. If B overrides some functionality of A, then usually the language provides a facility to call the base class implementation (base.Foo() or some such).
Inheritance Example: C#
public class A
{
public void Foo() { }
public virtual void Baz() { }
}
public class B : A // B extends A
{
public void Bar()
{
this.Foo(); // Foo comes from A
}
public override void Baz() // a new Baz
{
base.Baz(); // A's Baz
this.Bar(); // more stuff
}
}
If, on the other hand, you have used composition instead of inheritance and B contains an instance of A as a class variable, then you would need to create an object of A and reference it's (public) functionality through that instance.
Composition Example: C#
public class B // use A from above
{
private A MyA { get; set; }
public B()
{
this.MyA = new A();
}
public void Bar()
{
this.MyA.Foo(); // call MyA's Foo()
}
}
depending on the access level (would be protected or public in .NET), you can use something like:
base.method(argumentlist);
the base keyword in my example is specific to C#
there is no need for an instance of class A, because you already have a class A inherited instance
Basically you need a reference to the parent class.
In PHP:
parent::example();
From: http://www.php.net/manual/en/keyword.parent.php
<?php
class A {
function example() {
echo "I am A::example() and provide basic functionality.<br />\n";
}
}
class B extends A {
function example() {
echo "I am B::example() and provide additional functionality.<br />\n";
parent::example();
}
}
$b = new B;
// This will call B::example(), which will in turn call A::example().
$b->example();
?>
I find that the best way to tame the complexity of inheritance is to ensure that I only make B inherit from A when it really is a specialization of the superclass. At that point, I can call A's methods from inside B just as if they were B's own methods, and if B has overridden them then I can only suppose that this must be for a good reason.
Of course, quite often it is useful for B's implementation of a method to invoke A's implementation on the same object, generally because the subclass is wrapping extra behavior around the superclass's basic definition. The way in which you do this varies between languages; for example, in Java you do this:
super.methodName(arg1, ...);
Here's a quick Java example:
public class Aclass
{
public static void list_examples()
{
return("A + B = C");
}
}
public class Bclass extends Aclass
{
public static void main(String [] args)
{
System.out.println("Example of inheritance "+list_examples);
}
}
Note that the method for accessing the parent class shouldn't change. Because you are extending you shouldn't have to say parent:: or anything unless you are overriding the parent method / function.
It seems to me that extending your class might not be your best option. Class "B", "C", and "D" should only extend class "A" if they are truly an extension of that class, not just to access some method. For instance "Huffy" should not extend "BrandNames" just because "Huffy" is a brand name and you want access to one of the methods of "BrandNames". "Huffy" should instead extend "Bicycle" and implement an interface so the methods of "BrandNames" can be used. An additional benefit here is that (in Java) multiple interfaces can be used but a class can only be extended once. If in your example class "B"' needed to access a method from class "A" that could work, but if class "C" needed to access a method from class "A" and class "'B"' then you would have to use an interface in class "'C".