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:
- Create an
ISpeaker
interface. - Add a
speak()
method toISpeaker
. - Implement this interface with a
Speaker
class. - The
Creature
class should be inherited fromISpeaker
. - Then add a delegate to the
Creature
class. Thes
peak
method would redirect calling ofspeak()
to the delegate. - 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
.

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

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

Step 4
This code should be created:

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

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

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.

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

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

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

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.

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.

Step 13
Edit the run-configuration.

Step 14
You'll see this dialog:

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

Step 16
Enter the details as shown here:

(This way we can be sure we'll see the trace.)
Step 17
Run the compiled SWF. A "Hello!" message appears in the console.

Here's what we obtain:
- Code of interface and of implementation are bound up with navigation tools and bookmarks in editor.
- Code is now well-organized. Every implementation has a name: an interface name + "
Impl
". - Boost of the usability. In a class that uses this behavior, we only add our interface to the
implemented
list. - 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.

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:

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:

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".
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post