Abstract classes in ActionScript

-allow-abstract-classes

Apache Royale adds support for declaring abstract classes in ActionScript. An abstract class cannot be instantiated using the new keyword, meaning that it must be subclassed. Additionally, an abstract class may declare abstract methods that do not have a function body. Abstract methods must be implemented by the concrete subclass, similar to how the methods of an interface must also be implemented.

Compiler option

Royale enables abstract classes by default. To disable abstract classes in your application, use the -allow-abstract-classes compiler option.

mxmlc -allow-abstract-classes=false MyApp.mxml

Code example

Consider the following code that creates a class named GraphicsObject:

package
{
	public abstract class GraphicsObject
	{
		public function GraphicsObject()
		{
		}

		public var x:Number;
		public var y:Number;

		public abstract function draw(context:IGraphicsContext):void;
	}
}

This class uses the abstract modifier, so if we tried to instantiate the class directly, we’d get a compile-time error:

// Error: Abstract classes cannot be instantiated with the new operator.
var object:GraphicsObject = new GraphicsObject();

The GraphicsObject class defines a method named draw() that also uses the abstract modifier. This method does not have a body, and it will need to be implemented in a subclass.

The IGraphicsContext type used by the single parameter of draw() is a hypothetical interface that (for the purposes of this example) we’ll say has two methods, named moveTo() and lineTo().

The next code sample shows how to extend the abstract class GraphicsObject and implement its draw() method:

package
{
	public class Rectangle extends GraphicsObject
	{
		public function Rectangle(width:Number, height:Number)
		{
			this.width = width;
			this.height = height;
		}

		public var width:Number;
		public var height:Number;

		public abstract function draw(context:IGraphicsContext):void
		{
			context.moveTo(x, y);
			context.lineTo(x + width, y);
			context.lineTo(x + width, y + height);
			context.lineTo(x, y + height);
			context.lineTo(x, y);
		}
	}
}

If we extended GraphicsObject and did not implement its abstract method, we’d get a compile-time error:

package
{
	// Error: Method draw in abstract class GraphicsObject not implemented by class Foobar
	public class Foobar extends GraphicsObject
	{
		public function Foobar()
		{
		}
	}
}

Limitations of abstract classes in Royale

Checking whether a class is abstract happens at compile-time only. However, by using reflection APIs, a developer could potentially gain access to an abstract class and instantiate it at run-time without errors.

If a SWC library contains abstract classes, applications using that library must also enable abstract classes before the compiler will enforce any restrictions.

Other ActionScript compilers, such as the one in the Apache Flex SDK, may not recognize or enforce private constructors. Attemping to pass source code or SWC libraries that contain classes with private constructors to another compiler may result in compile-time errors or unexpected behavior at run-time. In other words, to write 100% portable ActionScript code that works with any compiler, avoid using abstract classes and any of Royale’s other extensions to the ActionScript language.