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