The final concept I cover in this article is polymorphism. The concept behind polymorphism is based on the idea of different classes implementing the same method names.
Even though this is a very simple concept, polymorphism has some interesting implications. The first major advantage is that it allows classes to be interchangeable at runtime. There are no hard-coded references to specific method names for specific classes.
For example, imagine you have a Teacher class and a Student class. You could implement a teach method for the teacher and a study method for the student, but polymorphism allows you to write the code so that the two classes both implement a work method. Although a Teacher and Student class will clearly have a different implementation of a work method (one teaches, the other studies), you can use a shared generic method name, creating a single interface through which they can be accessed:
Teacher.as
package com.adobe.ooas3 {
public class Teacher {
public function work():void {
trace("I am teaching");
}
}
}
Student.as
package com.adobe.ooas3 {
public class Student {
public function work():void {
trace("I am studying");
}
}
}
Any class that gets passed an instance of either the Teacher or Student class does not need to do any type checking to determine whether it is dealing with a teacher or a student instance (or any other class implementing the same methods for that matter) but it can directly call the work method.
You can enforce polymorphism between classes through the use of something called interfaces. These are similar to classes in that they define a set of methods, but interfaces are different than classes because they do not have an implementation. Interfaces simply define a "contract" of the methods a class needs to implement in order to be valid.
Here's an example of an interface called IWork:
IWork.as
package com.adobe.ooas3 {
public interface IWork {
function work():void;
}
}
As you can see from the code above, an interface looks suspiciously like any other class. But there are a few differences. Most developers choose to name an interface name so that it begins with a capital I (a common naming convention for interfaces, although it is optional). Also, instead of a class
keyword, interfaces use the interface
keyword. Additionally, as you analyze the code, you'll see that in the section where you would expect to see some code for the work method, only its method signature is defined.
The interface above requires that any class that implements it must have a method called work
that has a return type of void
.
Let's see how the Teacher and Student class implement this interface:
Teacher.as
package com.adobe.ooas3 {
public class Teacher implements IWork {
public function work():void {
trace("I am teaching");
}
}
}
Student.as
package com.adobe.ooas3 {
public class Student implements IWork {
public function work():void {
trace("I am studying");
}
}
}
That was easy. By simply adding the implements
keyword, you now have set up both the Teacher and Student classes so that they are required to implement the work method. If you try removing or renaming the work method from either of the two classes, you'll receive a compile-time error message.
By having classes all implement a common interface, the interface can actually be used as a data type. Let's look at the following example:
Supervisor.as
package com.adobe.ooas3 {
public class Supervisor {
public function Supervisor(worker:IWork) {
worker.work();
}
}
}
In the example above, you have a Supervisor class that can be passed an instance of a class implementing the IWork interface. In this way, the interface is being used as a data type.
The ActionScript compiler knows that any class instance implementing this IWork interface will have the work method defined. Therefore, it doesn't complain about a possibly undefined method when the code is compiled.
You can quickly test the Supervisor class by pasting the following code on the first Frame in the main Timeline of a blank FLA in Flash CS3 Professional:
import com.adobe.ooas3.*;
var supervisor1:Supervisor = new Supervisor(new Teacher());
var supervisor2:Supervisor = new Supervisor(new Student());
If you run Test Movie (Control > Test Movie), you'll see two lines appear in the Output panel. The first line displays "I'm teaching" and the second displays "I'm studying" (see Figure 3). These trace
statements are, of course, exactly what you'd expect by passing a new teacher and student instance to the Supervisor constructor.
Figure 3. Output panel of the Supervisor class using polymorphism
Type casting
That brings up the next question: What happens when you try to access class-specific methods or properties of Teacher or Student (other than the work method) that weren't defined in the interface?
The Supervisor class uses the IWork data type for any instance that is passed to its constructor – so if you were to call any other method, the compiler has no way of knowing whether that is implemented. The compiler will report an error.
You can work around this is by using something called type casting by converting the instance from this generic IWork data type back to the Teacher or Student instance.
The way this is accomplished is by using the is
and as
keywords, as follows:
package com.adobe.ooas3 {
public class Supervisor {
public function Supervisor(inst:IWork) {
if(inst is Teacher) {
var teacher:Teacher = inst as Teacher;
trace(teacher.tenure);
}
if(inst is Student) {
var student:Student = inst as Student;
trace(student.averageGrade);
}
}
}
}
In the code above, the is
keyword checks whether the worker instance passed to the constructor is of the specific type Teacher or of the type Student.
If it is a teacher instance using the as
keyword, you are able to type cast the instance to that specific class, so you can access its specific methods and properties. In this case you could, for example, have a Boolean tenure property set in the Teacher class.
The same holds true if we're dealing with a student instance. If the is
keyword confirms that you are working with a student, you can type cast the generic IWork instance to a student instance and access the averageGrade
property.
This is a very useful behavior. You can see how using polymorphism in this way benefits your projects when you have a collection of classes that need to accept any number of data types, as long as they implement a common interface. When you need to get into the specific method implementations of the class implementing the interface, type casting makes this possible.
Where to go from here
This article walked through the basics of object-oriented programming in ActionScript 3.0. From the concept of classes, the building blocks of your application, through inheritance, encapsulation, and polymorphism.
You learned how classes can extend each other through subclassing or by using composition. Additionally, you now know how to restrict access to your class by using access modifiers and providing an API with getter/setter methods. Finally, you've seen how you can enforce multiple classes to implement the same set of methods through the use of interfaces and how to convert generic instances back to a specific implementation by using type casting.
That's quite a feat. If you've followed along, you are now ready to start putting these new concepts into practice and reap the benefits of object-oriented programming in your ActionScript 3.0 projects.
Be sure to check out the ActionScript Technology Center for more in-depth articles and tutorials, and to gain more knowledge of working with ActionScript 3.0.
If you haven't already, take a look at the Flash Quick Starts to get more specific information about classes and programming tips on developing Flash applications in ActionScript 3.0.
hai visit www.softwaaree.blogspot.com for more detailed study
ReplyDelete