Comments on: Runtime Enforcement of Abstract Classes in AS3 https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/ Archive of older blog posts written by Josh Tynjala about Flash, Flex, and ActionScript Wed, 26 Jun 2013 02:52:46 +0000 hourly 1 https://wordpress.org/?v=4.9.9 By: Oliver https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-50320 Sat, 08 Sep 2012 08:42:20 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-50320 I understand that this is a really old article, but I’d been doing a bit of quick thinking and while not tested I believe this solution might work a tad bit nicer for deep tree structures of abstract classes sprinkled with leaves of concrete classes (which is the case in my project):
1. For the root abstract class (which is just one of many abstract classes that directly and indirectly extend this), have a protected boolean variable initialised to false that signals whether or not instantiation has succeeded
2. Write an if statement in the root abstract class’ constructor, throwing an error if the boolean is set to false
3. In each concrete class, ignoring all abstract classes inbetween, set this boolean to true and then call the root abstract class’ constructor

Please do feel to mention if this idea is flawed, however I’ll be implementing it in a bit

]]>
By: Josh Tynjala https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-23476 Sun, 11 Dec 2011 01:40:07 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-23476 Seems like a reasonable approach, Solstice_Of_Light. Usually, what I do these days is create an interface, implement all of its methods in a base class, but leave out the implements IWhatever. Then, then subclass needs to do it. Enforcing anything else beyond that amounts to busywork, in my opinion.

]]>
By: Solstice_Of_Light https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-23470 Sun, 11 Dec 2011 01:02:11 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-23470 Couldn’t you emulate an abstract class with errors at compile time by splitting the problem in two? Your base class is a normal class which contains all the pre-defined methods. A second (supplementary) class is an interface with all the to-be-implemented methods. The base class REQUIRES that an (implemented) version of the interface is passed in the constructor.


Class pseudo-abstract{

private var implementedmethods:IUnimplementedmethods;

public function constructor(implementedClass:IUnimplementedmethods){

this.implementedmethods = implementedClass;

}

public function implementedfunction(){

…code…

}

public function unimplementedmethod(){

implementedmethods.unimplementedmethods();

}

}

I’m not an actionscript user, so please excuse my syntax …
Note that you could even emulate overriding by “try{implementedmethods.implementedfunction()}
catch(error){…code…}”
if there’s anything similar available in AS.

]]>
By: Peter Painter https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-17637 Fri, 23 Sep 2011 13:20:58 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-17637 One thing about abstract classes that has been completely ignored so far is that an interface cannot declare Events, Styles etc.

So all the support in Flex Builder and MXML for easy creation of event handlers and style properties fails if your MXML class has a member that is defined by just an interface.

For detection of a direct instantiation, I don’t use a self parameter. I rather compare the class name of the current this pointer with the static class name:

if( flash.utils.getQualifiedClassName(this).substring(2+flash.utils.getQualifiedClassName(this).indexOf(“::”))==”myClassName”) { throw Error…};

Some of my abstract classes contain a static function that instantiates the proper descendant based on additional parameters.

Things would be much easier if you could simply declare the constructor of the base class as protected. All that is to for implementing this is to remove the error check for a non-public constructor from the compiler and it should work as expected. I’m sure the compiler would do the right thing (and throw the right errors) if you only could get past the ‘constructors must be public’ check.

Even a private constructor could be useful, when designing a managed class.

]]>
By: Steve Thorpe https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-15683 Wed, 17 Aug 2011 21:02:24 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-15683 And rather than maintain an array of abstract methods a unique prefix naming convention could be applied to abstract methods and used to search for them in the reflection. for example if a double underscore prefix (“__”) is used uniquely for abstract method names then during instantiation the following code, implemented in the constructor of MyAbstractClass, will throw an error on the first abstract method it finds which is not implemented in the subclass.

var methods:XMLList = describeType(this).method;
for (var m in methods){
	if ((methods[m].@name.substr(0,2) == "__") && (methods[m].@declaredBy == "MyAbstractClass" )){
	throw Error(methods[m].@name + " is an abstract method, not implemented in subclass:" + Object(this).constructor);					
	}
}
]]>
By: Steve Thorpe https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-15676 Wed, 17 Aug 2011 18:22:50 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-15676 Similar to Shaun’s solution (requires no special processing in subclasses) but works in Flash Pro as well as FB :

In constructor of MyAbstractClass add:

if (Object(this).constructor == MyAbstractClass)
     throw new Error("MyAbstractClass is an abstract class");
]]>
By: Shaun https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-12719 Thu, 30 Jun 2011 19:54:05 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-12719 Sorry to amend my original post, the class CommonParserBase is my abstract class and this code would live in that classes constructor, essentially saying if an object calls this things constructor it has to be some object typed as something else (that is a subclass).

]]>
By: Shaun https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-12718 Thu, 30 Jun 2011 19:52:31 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-12718 Know this is an oldie, but just figured I’d tag another solution into here that seems to work fine at least in my current version of FB 3.4

In the constructor:

if(getClass(this)==CommonParserBase)
    throw new Error("This class is abstract only instantiate sub-classes.");

It results in a string comparison and requires no changes to the constructor of the abstract or concrete sub classes. I still have no good solution for finding un-implemented methods, the best I can think of is to break apart the interfaces and have the sub-classes implement a secondary interface which essentially contains what you would consider the unimplemented methods of the abstract class (in essence achieving the goal but with more files than should be necessary and possibility for confusion where abstract classes would make this clear). Also @Zeljko I think there’s a decent explanation of why you would do this above, if you ever use abstract classes in another language such as Java (among other things I miss from Java like overloading) you’d be able to more easily understand why this is really nice to have.
http://download.oracle.com/javase/tutorial/java/IandI/abstract.html
http://www.javacoffeebreak.com/faq/faq0084.html
What it comes down to is the abstract class acts much like an interface requiring certain implementations to be handled by the implementing class, however unlike interfaces, abstract classes can contain some of the functionality. As an alternative to my suggestion of breaking down the interface you could also just create a test case that calls all the methods and in the “abstract” version have it throw an error, create an instance of each concrete class in the test then call all methods of the “abstract” class that require concrete implementation. This avoids the overhead of the run time solution and would help catch errors early, the only caveat is having to use a test framework like flex unit to execute the test class.

]]>
By: Zeljko https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-11236 Fri, 10 Jun 2011 17:00:46 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-11236 Like every advanced tutorial, in this also some thing is missing. The answer to question “Why to use it?”

]]>
By: Magic https://joshblog.net/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-10628 Tue, 31 May 2011 22:14:03 +0000 http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/#comment-10628 Hi,

There’s a bit simpler way of faking an abstract class.

package
{
    public class AbstractClass
    {
        public function AbstractClass()
        {
            if(String(super) == "[object AbstractClass]") throw new Error("This class is abstract and it cannot be instantiated");
        }
     }
}

Cheers.

]]>