Adding Multiple Inheritance to AS3 with Traits and Realaxy Editor


In this post you'll learn about a language extension called Traits, a feature of a new Beta of RASE, a smart and modern IDE for Adobe Flash based on Jetbrains MPS. Traits will allow you to use multiple inheritance in your projects, so a class can effectively extend two other classes.

The sample project was created with ActionScript 3.0 with Traits language extension using Realaxy ActionScript Editor (RASE). If you want to do it the same way, RASE can be downloaded here (if you are new to RASE please follow the Beginners guide here)

Why Use Multiple Inheritance?

ActionScript is a modern object-oriented language. At the moment, actual OOP defenition and interpreting assume that multiple inheritance is a vicious practice. Thus, AS itself does not permit multiple inheritance, and only the using of interfaces provides an alternative. It's all well and good, no need to argue.

However, sometimes it seems unbearable. It happens that owing to this missing feature we make our code too sophisticated or even probably messy.

For instance, we have a class Creature, which already extends Sprite. We want to teach it how to speak. "A proper OOP" imposes us to make a composition. So we need to:

  1. Create an ISpeaker interface.
  2. Add a speak() method to ISpeaker.
  3. Implement this interface with a Speaker class.
  4. The Creature class should be inherited from ISpeaker.
  5. Then add a delegate to the Creature class. The speak method would redirect calling of speak() to the delegate.
  6. Well, it's done.

Let's imagine we have multiple inheritance. Then we make a Speaker class, inheriting our Creature class from the Speaker. That's all, folks.

Then, imagine our Creature should be able to do a lot things: to walk, to move arms and legs, to eat, to smile, to cry. Maybe also to fly. You never know what kind of requirements could become a part of the spec. As a result, we gain hundreds and thousands of lines of a "proper" OOP code, which is so redundant and verbose, that understanding its real purpose would be difficult even to its author.

We, skilled Flashers, understand that the situation described is purely artificial. Who would create a pack of interfaces for every aspect of behavior? Even if those would be applicable not only for Creature. Indeed, the real code would look different, not so pretty and learnedly, but closer to the real world - that is to say, simpler.

So it turns out that the best intentions of ECMAScript's (and, later, ActionScript's) designers to create a modern and correct OOP language accommodate badly for our everyday work.

Enough complaining! We have a tool to fix it. RASE. Realaxy ActionScript Editor. This solution is Traits, an AS3 language extension.

Let's proceed to action.

Step 1

First, create a new project with testTraits module containing main-class Creature.

Figure 1

Step 2

Enter the project details as shown here, and click Next:

Figure 2

Step 3

Create a new class called Creature, in the package com.example:

Figure 3

Step 4

This code should be created:

Figure 4

Step 5

Import a traits language by pressing Ctrl+L (or Command+L).

Figure 5

Step 6

Create a Speak interface with a single "speak" method.

Figure 6

Step 7

The lower part of the window has two tabs, "Interface" and "Trait".

Select the "Trait" tab (colored with gray) and click on the empty editors field. A dialog box appears, offering us to create a new trait.

Figure 7

Step 8

After "OK" a default implementation is created by editor. Note how this is now trait Speak rather than interface Speak:

Figure 8

Step 9

Add a body to the "speak" method: just trace "Hello!" to the console.

Figure 9

Step 10

In the Creature class add a "Speak" interface to "implements".

Figure 10

Step 11

The editor added an "i" to the right of the interface name. It means that the interface has a default implementation -- it has trait behavior.

Figure 11

Step 12

RASE recognizes such behavior and does not highlight any error when methods are added to class.

That's it! Our Creature can talk now! Add a call of method speak() to a class constructor to prove it.

Figure 12

Step 13

Edit the run-configuration.

Figure 13

Step 14

You'll see this dialog:

Figure 14

Step 15

Press the "+" button to add a new Configuration, and select ActionScript.

Figure 15

Step 16

Enter the details as shown here:

Figure 16

(This way we can be sure we'll see the trace.)

Step 17

Run the compiled SWF. A "Hello!" message appears in the console.

Figure 17

Here's what we obtain:

  1. Code of interface and of implementation are bound up with navigation tools and bookmarks in editor.
  2. Code is now well-organized. Every implementation has a name: an interface name + "Impl".
  3. Boost of the usability. In a class that uses this behavior, we only add our interface to the implemented list.
  4. Keeping apples and oranges separate. Code of Creature class is not "littered" with excessive entities. We've just ordered the Creature to talk.

As a result, we have behavior that is really like multiple inheritance but stands on "proper and correct" OOP recommendations.

Step 18

Let's see how it works, by looking at the code we're actually generating.

Click "Build->Generate (obsolete)->Generate Text from Current Model". The newly generated code of the Creature class appears in the Output window.

Figure 18

The code demonstrated above implements a classical composition. The trait language extension hides redundant entities and organizes relationships between code artifacts. In fact, we operate a "pure" OOP code.

Now we see a new fast and easy way to teach our Creature how to do everything. The main thing is the behavior: we apply the same ground rules to another classes.

Let's do it in 5 minutes.

Step 19

Add some new traits -- one for each limb -- just as we did before:

Figure 19

Step 20

The Creature class gets now a lot of new skills, but its code remains easily-readable and clean. Without the Traits language extension it would be completely different:

Figure 20

It's time to say goodbye. I'm waiting for your questions, suggestions and comments.

Remember, if RASE is new to you, please read the "Beginners Guide".

Related Posts
  • Code
    iOS SDK
    Exploring the Multipeer Connectivity framework: Project Setup78mpi preview image
    As with every major release, iOS 7 includes many new APIs that developers can take advantage of in their applications. In this tutorial, we'll take a look at a brand new framework introduced in iOS 7, the Multipeer Connectivity framework. This framework adds support for discovering, connecting to, and communicating with nearby services, such as iOS devices. In this tutorial, I will show you how to create a simple, multi-player game using this new framework.Read More…
  • Code
    SOLID: Part 2 - The Open/Closed Principle2 ocp retina
    Single Responsibility (SRP), Open/Closed (OCP), Liskov's Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you need to write code.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Blocks0e5ds8 preview image@2x
    Blocks are actually an extension to the C programming language, but they are heavily utilized by Apple's Objective-C frameworks. They are similar to C#'s lambdas in that they let you define a block of statements inline and pass it around to other functions as if it were an object.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Categories and Extensions0e5ds8 preview image@2x
    Categories are an Objective-C language feature that let you add new methods to an existing class, much like C# extensions. However, do not confuse C# extensions with Objective-C extensions. Objective-C's extensions are a special case of categories that let you define methods that must be declared in the main implementation block.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Hello Objective-C0e5ds8 preview image@2x
    This chapter is designed to help you acclimate to Objective-C programming style. By the end of this chapter, you will be able to instantiate objects, create and call methods, and declare properties. Remember that the goal is to provide a very brief survey of the major object-oriented aspects of Objective-C, not a detailed description of each component. Later chapters fill in many of the conceptual details omitted from this chapter.Read More…
  • Code
    Android SDK
    Android SDK: Java Application ProgrammingAndroid preview@2x
    Our goal in this series is to learn about Android SDK development. So far we explored the development tools, looked at the structure of an Android app project, started to create a user interface, and responded to user interaction. In this tutorial, we will look at the basic structures and concepts in Java that you need to know in order to start developing apps for Android.Read More…