Chapter 9:Objects
This chapter will continue the study of objects, touched on briefly in previous chapters. When studying this chapter, you will
- continue your introduction toprogrammer-defined object classes, constructors and methods
- compare the use of parallel structures and objects to represent behavior
- get practice building a Flash application involving process movie clips, programmer-defined objects, the with statement, and arrays
Motivating Example
The game featured in this chapter is the same Memory/concentration game described in the previous chapter. The purpose of repeating a game is to demonstrate programmer defined objects in ActionScript and, moreover, provide an implementation to compare with the HTML/JavaScript implementation.
The opening screen of this Flash application is shown in Figure 1. The rectangles represent the backs of cards. The purpose of the game is to click on two cards to see if the faces match.
Figure 1. Opening screen shot of Flash Memory game.
Figure 2 shows the screen after the player has clicked on two cards that were not a match. Keep in mind that this display would be quickly replaced by a display showing just the virtual backs of the cards.
Figure 2. Screen showing a mis-match selection.
Figure 3 shows the display after cards have been (virtually) removed following a successful match. The removal is easy to accomplish because the movie instances representing the cards can be made invisible.
Figure 3. Screen showing cards removed after a successful match.
The Memory game to be implemented in Flash requires the same features cited in the previous chapter:
- a way to represent the game board, namely the cards as images that can change back and forth between an image representing the common card back and images representing the card face
- a way for clicking on the card to invoke a function
- variables representing the state of the game so that the function can distinguish first turn and second turn and, upon the second turn, compare the two card faces
- a way to simulate shuffling of the cards
- a way to insert a pause so that the player has time to study the card faces
- a way to determine when the game is over. There is no way in the basic game for the player to lose, but it is necessary to determine when the player has won by matching all the pairs of cards.
- a way to prevent a player from clicking on more than two cards. Since there will be a pause after clicking on the second card, a fast player could keep clicking to reveal more card faces.
Introduction to concepts
Object-oriented programming (OOP) puts code and data together in a way that can make the internal computer programming resemble the real-world objects and situations they are intended to represent. Object-oriented programming has its own vocabulary and often is viewed as an advanced topic with a special mystique. However, objects are anything but abstract, so do not be intimidated by anything you may have read or heard about OOP being difficult. The built-in objects of Flash will serve as good examples. The exposition also will cover programmer-defined objects.
Certain purists would take the position that Flash and ActionScript are not object-oriented because applications are not constrained to use only objects. Specifically, global variables and functions are allowed and it would be difficult or, at the least, awkward to avoid their use. This book takes a relaxed view. It is possible to define object classes in ActionScript and the built-in constructs of the language are objects. Furthermore, the fact that the Flash environment forces the programmer to associate code with frames, buttons and movie clips is very much in the spirit of object-oriented programming.
Description: classes, objects, methods and constructors
A classdefines the workings of a set of objects. A programmer uses the facilities of the specific language to define the members of the class: the data, termed variables, attributes or properties, and code, termed methods. Actual objects or object instances of the defined class are created, generally using the same format as declaring variables for the built-in types such as integer.
Each member variables or methods can be designated asa class variables or class methods or as an objectvariables or objectmethods. Each instance has its own set of the object member variables and the object methods can access and change the values of the member variables. In contrast, there is only one copy of each class variable.
You have seen Math.random in use in previous chapters. It is a class method and is available for use independent of any object instance. An example of a class variable is Math.PI, which has the additional characteristic that it is a constant or final variable: it cannot be changed.
One use of a class variable is to keep track of the number of objects created. This class variable will change in value, but it is essential that it be a single variable. Class methods are procedures that are invoked independent of any object of the class. It is not necessary for there to be any objects declared for the class. Object methods generally refer to object variables.
Assuming that a class is not defined as containing only class variables and class methods, using objects involves at least two distinct steps: defining the class and creating objects of that class.In Java, an object is created when the operator new is invoked as part of a declaration. One of the methods defined as part of the class is the constructor method. This method typically initializes the object variables. It may access and modify class variables. The constructor is invoked when an object is created.
Consider the following example defined in a pseudo-code for setting up characters in a computer game. Each character has a position, a strength factor, a value if captured, and bag of treasures, initially empty. There are object methods for ascertaining the value, weakening and strengthening the character, and adding to its treasures. There is a method for obtaining the count of characters created. There would be more methods, but this is a start.
TECHNICAL NOTE: Note that this pseudo-code assumes the existence of a type of aggregation corresponding to unordered finite sets (look up the language SETL). Most languages would use arrays for this purpose.
The constructor method shown sets the strength and the value at a default value.
class Character
class variable: integer count_of_characters = 0;
object variable: position [integer, integer];
object variable: strength integer;
object variable: value integer;
object variable: treasure_bag set;
objectmethod: constructor:
strength = 100;
value = 10;
treasure_bag = empty_set;
position[0] = 0;
position[1] = 1;
count_characters = count_of_ characters+1;
class method: how_many():
return (count_of_characters);
object method: worth():
return(value);
object method: weaken(f):
strength = strength – f;
object method: strengthen(f):
strength = strength + f;
object method: add_to_treasure(stuff):
treasure_bag.add(stuff);
object method: place (x,y):
position(0) = x;
position(1) = y;
object method: move_along():
position(0) = position(0)+1;
Instead of using pseudo-code, here is the Java statement that would both declare the variable my_character to be of type character and also create an object of the character class and assign it to my_character:
Character my_character = new Character();
In Java, the method with the same name as the class name is the constructer. The corresponding ActionScript statement will be shown in the featured application.
Generally, the methods and variables of an object are referenced using dot notation, so
my_character.weaken(penalty);
would invoke the weaken method indicated above and cause the strength variable for my_character to decrease by an amount equal to penalty.
In any language supporting objects, if there is no constructer method defined, then the default constructor simply allocates space for any object variables. It also is possible in many systems to have more than one constructer. This is supported using a general facility called over-loading of methods or operators.
TECHNICAL NOTE: Recall that the + operator in many languages, including JavaScript and ActionScript, has one meaning when it is used with numbers and another when it is used with strings. This is an example of over-loading.
The language processor examines the datatypes of the operands and uses the information, the signature, to determine which operator to invoke. Similarly, methods can be defined with different parameters, different in terms of number and datatype. The language processor examines the calling expression to determine which method to invoke. The game character example may have the constructor shown above be the default and another constructor for setting specific amounts for the strength and value variables:
objectmethod: constructor(s,v):
strength = s;
value = v;
treasure_bag = empty_set;
count_characters = count_of_ characters+1;
EXAMPLE: The Flash Memory application makes use of programmer defined objects to represent cards.
Description: inheritance, overriding, polymorphism
Classes can be defined as extensions of other classes. The subclassinherits properties and methods from the superclass. You, the programmer, can 'have it both ways': you can re-use some of the coding defined for the superclass for the subclass, saving writing and debugging time, and you can add new versions of some methods, over-riding the definitions in the superclass. Suppose the game described here had characters that had defenses against being weakened and that moved along at a quicker pace. This characteristic could be represented by Special being defined as a subclass of Character. The definition, using the abstract pseudo-code introduced above, would be:
class Special inherits Character
object variable: defense float;
object method: constructor(d):
Character();
defense = d;
object method: constructor(d,s,v):
Character(s,v);
defense = d;
object method: weaken(f):
strength = strength – f*d;
object method: change_defense(d):
defense = d;
The code indicates that a Special character is like a regular character, but has one extra property, the defense factor, and one extra method. Variables of type float are numbers represented in floating point notation, also called mathematical notation. These can be numbers with fractions, such as
1.5
0.333333333
-104.30279
A Special character is constructed using the signature to pick the appropriate constructor method. Each of these methods call a constructor defined for Character and then executes one more statement. The weaken method for Special objects is different than the weaken method for [regular] Character objects. This is called polymorphism: the methods can take many forms. Please note that everything is still-well defined enough to permit a compiler to translate a program correctly and, most importantly, catch errors.
Many languages enforce single inheritance: a new class can be the subclass of at most one superclass. This restriction still allows for fairly elaborate inheritance structures. Figure 4 shows an inheritance tree for a game involving different types of characters.
Figure 4. Inheritance tree example.
The subclasses of any one superclass do not have to differ from the superclass in the same way. The Flying class may have an added object variable relating to movement and a different move_along method that makes use of the object variable. Objects in the class may use the weaken method of Character.
A characteristic of object-oriented programming is that there would be statements such as
piece.weaken(penalty);
in the code instead of (writing in pseudo-code)
if (piece corresponds to a Special)
do it this way
else do it the other way
The logical test to determine what type of piece is built into the object-oriented language facilities of the language.
EXAMPLE: The Memory application will make use of the built-in movie clip object and define methods for movie clips to be inherited by the movie clips that are part of the programmer defined card objects.
Description: information hiding
Information hiding refers to the feature in object-oriented languages that the exact implementation of objects is hidden in the class definition. This includes the structure of the variables and the statements in the code of the methods. Some object-oriented languages have modifierssuch as private or publicthat specify the access to each variable and method. For example, it may be forbidden for code outside of the class definition to use
my_character.value
If code outside the class definition needs this information, there would be a method called worththat displays it.
The implication here is not that matters are kept secret but that a discipline is established to use the methods and variables in a prescribed way. This will make it easy to change the specific implementation if the situation demands that this be done.
HISTORICAL NOTE: The best illustration of the value of this feature is what was called the Y2K problem. Much software was written to use only 2 digits for the year part of a date. The software remained in operation far longer than the original programmers predicted and needed to be fixed before 2000. The "problem" in the Y2K problem was not that people did not know how to adapt the code. It was that coding involving dates was spread throughout many, many programs and it was necessary to examine code, some of which was only in executable form, not source form, to find the places to change. If object orientation had been used to confine the handling of dates to one place in each application, changing the date would not have cost large amounts of money and little confidence that all places had been changed.
Description: is-a versus has-a
A class definition can be built on another class as indicated above and a class definition can include variables that are themselves objects. The phrase is-a refers to the first situation and the phrase has-a refers to the second. The featured example in this chapter involves a card object that has-a movie clip object as one of its variables. Though these two relationships are quite different, they can be confused.
Reading Checks
- Describe what is meant by a class and an object of that class.
- Describe methods and constructor methods.
- What is inheritance?
- What do the terms 'is-a' and 'has-a' indicate for classes and objects?
- Explain operator overloading using + in JavaScript as an example.
Application
Review of previous examples
Object orientation is a fundamental topic and so it was expedient to include some uses before this chapter. You have seen uses of class methods of the Math class.
Math.floor()
for example, is a class method, independent of any object, that produces the greatest integer not larger than the parameter to the call.
The Document object model for HTML is what defines the components of a HTML document for JavaScript. For example, if there is a <form> named f with <input> tag with the name attribute set to "sum", then
document.f.sum.value = …
is the way to set the value attribute of this particular <input>.
In Chapter 7, you read about a simplified implementation in Java of the craps dice game. This application had a class called Game and a testing class called Crapstest that created a Game object and invoked methods to play out a game until it was won or lost.
Plan of attack for Memory
As you may have guessed, the Flash implementation will use programmer-defined objects for the representation of individual cards and for the game. An array variable, cards, will hold the deck, so to speak, each of the objects created using Makecard constructor. The Makecard object instance will include a movie clip instancerepresenting the back and the face of the card in frame 1 and frame 2 respectively. Each of these movie clips will contain button instances for the back of the cards. There will be code defined for all movie clips and, thus, inherited by the movie clip contained in the card, to simulate the action of flipping over and flipping back a card.
Makecard object has-a {circlecard, trianglecard, etc.) instance
circlecard movie clipis-a movie clip instance. It will inherit flipover and flipback methods defined for all movie clips.
circlecard movie cliphas-a button instance in frame 1. The on(release) code for this button invokes the turnover function.
circlecard movie cliphas-a graphic symbol (a circle) in frame 2
The Game object will hold the persistent information of number of matches, status with regard to first or second pick, and the value of the first pick. This is similar to the Java implementation of the game of craps.
Shuffling will be done by directly moving the cards on the screen.
The implementation of a pause will make use of processmovie clips. These movie clips do not contain any graphical material, but are vehicles for code.
The timeline of the main scene of the Flash document has a single frame and 3 layers you can name board, actions and process. The process layer contains an instance of the timersetup movie clip symbol. The timersetup symbol contains an instance of the timermonitor symbol. The timermonitor symbol is completely empty; the timersetup symbol is empty of graphical material, but has code in its single frame and code associated with the timermonitor instance. This will be explained in more detail in the next section.
You create new graphics, buttons and movie clips by using the Insert dropdown menu and clicking on New Symbol… and making the appropriate choice. You will do this to create the graphic symbols for the different card faces (4 in this implementation), movie clips for the different cards, the process clips (timersetup and timermonitor), a button for the back of the cards and a button to re-play a game. This is shown in Figure 5 displaying the Library.