Abstraction: Creating multiple keys

5.3 Abstraction: Creating multiple keys

We have reached a stage where we can create a piano key that reacts to one key of our com- puter keyboard and plays a single piano note. The problem now is obvious: When we create multiple keys, they all react to the same keyboard key, and all produce the same note. We need to change that.

The current limitation comes from the fact that we hard-coded the keyboard key name (“g”) and the sound file name (“3a.wav”) into our class. That means, we used these names directly, with- out a chance to change them short of changing the source code and recompiling.

When writing computer programs, writing code that can solve one very specific task—such as finding the square root of 1,764 or playing a middle-a piano key sound—is well and good, but not incredibly useful. Generally, we would like to write code that can solve a whole class of

Concept:

problem (such as finding the square root of any number, or playing a whole range of piano key

Abstraction

sounds). If we do this, our program becomes much more useful.

occurs in many different forms in

To achieve this, we use a technique called abstraction. Abstraction occurs in computing in many

programming. One

different forms and contexts—this is one of them.

of them is the technique to write

We shall use abstraction to turn our Key class from a class that can create objects that play a

code that can

middle-a when the “g” key is pressed on the keyboard into one that can create objects that can

solve a whole class of problems, rather

play a range of notes when different keyboard keys are pressed.

than a single spe- cific problem.

The main idea to achieving this is to use a variable for the name of the keyboard key we react to, and another variable for the name of the sound file we then want to play.

5.3 Abstraction: Creating multiple keys

Code 5.5 Generalizing for

public class Key extends Actor multiple keys: making

{ the key and note

private boolean isDown;

variable

private String key; private String sound;

* Create a new key linked to a given keyboard key, and * with a given sound. */

public Key(String keyName, String soundFile) {

key = keyName; sound = soundFile;

} // methods omitted.

Code 5.5 shows the start of a solution to this. Here, we use two additional fields— key and sound —to store the name of the key and the sound file we want to use. We also add two para- meters to the constructor, so that these bits of information can be passed in when the key object is being created, and we make sure that we store these parameter values into the fields in the constructor body.

We have now made an abstraction of our Key class. Now, when we create a new Key object, we can specify which keyboard key it should react to, and which sound file it should play. Of course, we haven’t written the code yet that actually uses these variables—that remains to be done.

We will leave this as an exercise for you.

Exercise 5.9 Implement the changes discussed above. That is, add fields for the key and the sound file, and add a constructor with two parameters that initializes those fields.

Exercise 5.10 Modify your code so that your key object reacts to the key and plays the sound file specified on construction. Test! (Construct multiple keys with different sounds.)

We have now reached a point where we can create a set of keys to play a range of notes. (Currently, we have only white keys, but we can already build half a piano with this.) This version of the project is in the book scenarios as piano-3.

Constructing all the keys, however, is a bit tedious. Currently, we have to create every piano key by hand, typing in all the parameters. What’s worse: every time we make a change to the source code, we have to start all over again. It is time to write some code to create the keys for us.

68 | Chapter 5 ■ Making music: An on-screen piano