CPSC 124, Spring 2006
Answers to Test #2


Question 1: Some short essay questions...

a) What is a package in Java, and how are packages used? Give an example of one of the standard packages that are part of Java.

Answer: A package is a collection of classes. It can also include nested packages. The purpose is to group related classes together. A package also acts as a "namespace" in the sense that classes in different packages can have the same name without conflicting. To access a class that is in a package, you must either use the full name of the class, including the package name, or import the class using an import statement. Examples of standard packages in Java include java.awt, which contains basic classes related to GUI programming, and java.net, which contains networking classes.

b) What does it mean to declare a member variable to be static final? Give one reason why you might want to do this.

Answer: A static final member variable is a constant whose value cannot be changed from the initial value assigned to the variable. One reason to declare such variables is that meaningful names are easier for a reader to understand than literal numbers. Another is that when it becomes necessary to give a different value to the constant, it will be easy to change the value in the one line where the constant is declared instead of having to hunt down all the occurrences of a literal value in the program code.

c) "A variable in Java can never hold an object, only a reference to an object." Explain what this means.

Answer: In Java, all objects are stored in a part of memory known as the heap. A variable "refers" to an object by storing the address of the object in memory. The address is the information that the computer needs in order to be able to find the object.

d) What, if anything, is the difference between a subroutine and a method? (Explain.)

Answer: The term method is used to refer to subroutines in the context of object oriented programming. That is, a method is simply a subroutine that is part of an object or of a class. In Java, every subroutine is a contained in an object or class, so as far as Java is concerned, there is really no difference between methods and subroutines (except for the technical point that constructors are subroutines but are generally not considered to be methods).


Question 2: If F is a temperature measurement in degrees Fahrenheit, then the same temperature in degrees Celsius would be 5*(F-32)/9. Write a Java subroutine that converts Fahrenheit to Celsius, where the Fahrenheit temperature is a parameter and the Celsius temperature is the return value. [This is easy!]

Answer:

        public static double fahrenheitToCelsius(double degreesFahrenheit) {
           double degreesCelsius = 5*(degreesFahrenheit - 32) / 9;
           return degreesCelsius;
        }

(The "public static" here is optional, since it was not specified in the problem.)


Question 3: Write a subroutine named replace that replaces each occurrence of a given character in a string with another given character. The original string and the two characters are parameters to the subroutine. The new string, after the replacement, should be returned by the subroutine. For example, the return value of replace("mesquite in your cellar", 'e', 'o') would be "mosquito in your collar". [This example from Sun's Java documentation]. Note that you should construct the new string one character at a time.

Answer: The idea of the subroutine is to start with an empty string. Then, for each character in the give string, add one character onto the new string. If the character in the original string is the character that we want to replace, then add the replacement character onto the new string. Otherwise, add the character from the original string onto the new string.

         public static replace(String str, int originalChar, int replacementChar) {
         
             String newString = "";  // start with an empty string
             
             for (int i = 0; i < str.length(); i++) {
                if (str.charAt(i) == originalChar)
                   newString = newString + replacementChar;
                else
                   newString = newString + str.charAt(i);
             }
             
             return newString;
         
         }

Question 4: Suppose that a color has red/green/blue components (r,g,b). Then its complement is the color with components (255-r,255-g,255-b). Suppose that you want to add a "Reverse Rectangle" capability to the MosaicDraw project. This command would change the color of each square in a specified rectangle to the complement of its current color.

Write a method that could be added to the program to perform this action. Like the fillRectangle method that you wrote previously, this method has parameters row1, col1, row2, and col2 to specify the corners of the rectangle. Recall that MosaicDraw has an instance variable named mosaic with methods mosaic.setColor(row,col,r,g,b), mosaic.getRed(row,col), mosaic.getBlue(row,col), and mosaic.getGreen(row,col). You will need to use all of these.

Answer:

         private reverseRect(int row1, int col1, int row2, int col2) {
         
            int startRow = Math.min(row1, row2);   // top row
            int endRow = Math.max(row1, row2);     // bottom row
            int startCol = Math.min(col1, col2);   // leftmost column
            int endCol = Math.max(col1, col2);     // rightmost column
            
            for (int row = startRow; row <= endRow; row++) {
               for (int col = startCol; col <= endCol; col++) {

                  int r = mosaic.getRed(row,col);    // components of current color
                  int g = mosaic.getGreen(row,col);
                  int b = mosaic.getBlue(row,col);
                  
                  r = 255 - r;   // components of complementary color
                  g = 225 - g;
                  b = 225 - b;
                  
                  mosaic.setColor(row,col,r,g,b);

               }
            }
         
         }

Question 5: Write a complete class definition for a class named Player that meets the following specifications: An object of type Player represents a player in a game. The object has private instance variables to represent the player's name and score. There is one constructor, with a parameter that specifies the player's name. (The player's score is initially zero.) The class defines methods for getting the player's name and score and for adding a specified number of points to the score.

Answer:

         public class Player {
         
            private String name; // the player's name
            private int score;   // the player's score
            
            public Player(String theName) {
               name = theName;
               score = 0;  // (This is not really necessary, since 0 is the default.)
            }
            
            public String getName() {
               return name;
            }
            
            public int getScore() {
               return score;
            }
            
            public int addToScore(int points) {
               score = score + points;
            }
         
         }

Question 6: a) Using the class defined in the previous problem, write Java statements (or a single statement) that will declare a variable of type Player, create an object to represent a player named "Spongebob", and store a reference to the object in the variable.

b) Given your answer from part a), write a Java command that will add 7 points to Spongebob's score.

Answer:The name of the variable in part a) can be anything you like, but the same variable name has to be used in part b). Also in part b), the name of the method must be the same as the name of the method that was defined in the class in the previous problem.

       a)    Player player = new Player("Spongebob");
       
       b)    player.addToScore(7);

Question 7: The idea of a black box has come up several times in this course. Discuss the "black box" concept, and explain how subroutines and classes can be regarded as black boxes.

Answer: A "black box" is a system that can be used without understanding its inner workings. The user simply needs to understand the interface, which specifies the connection between the black box and the outside. It is also important that the implementation of the black box -- the inside -- can be designed and built without detailed knowledge of how the black box will be used in larger systems. As long as the implementation correctly carries out the required function, the design is correct.

In a subroutine, the interface is the name, parameter list, and return value. This is all the information that a user needs in order to call the subroutine. The implementation is the code inside the subroutine. A user of the subroutine does not need to understand this code in order to use the subroutine. The writer of the subroutine does not have to know the details of the programs in which the subroutine will be used.

In a class, the "public" declarations in the class constitute its interface. The "private" declarations are part of the implementation (along with the code inside all the methods).


Question 8: The event-driven style of programming that is used in GUI programs is very different from the scripted, step-by-step programming that is often used for command-line applications. Discuss event-driven programs and how they relate to object-oriented programming. (What is an event? What does it mean to say that events are asynchronous? How does the programmer deal with the asynchronous nature of events? Why do objects fit in naturally with events?)

Answer: An event is something that occurs externally to the program and outside its control, such as when the user clicks the mouse or types a key or when data arrives over a network connection. Such events are asynchronous because they occur at unpredictable times, not at particular points in a "script". The program must be prepared to respond to events whenever they occur.

A programmer can deal with events by writing event-handling methods, which will be called by the system when the event occurs. For example, if a program needs to respond when the user presses a key on the mouse, it can define a mousePressed method. (It must also tell the system that it wants to receive mouse events by registering a "MouseListener" with the component that generates the events.) In general, the response to an event depends not just on the fact that the event occurred but also on the state of the program when it occurs. The programmer can use instance variables to keep track of the current program state. When an event-handling method is called, it can inspect those variables to find out what the current state is, and the response can include modifying the state of the program by changing the instance variables. For example, in the MosaicDraw program, the current drawing color is part of the program state. This part of the state changes when the user selects a new color, and the state is checked when the user draws something. This program is driven by the user's actions, since the user can select the new color or draw at any time, and the program must be prepared to handle those actions no matter when and in what order they occur.

Objects fit in naturally with events, because from the point of view of an individual object, messages coming into the object (that is, calls to its methods) are like events. The object does not control when or what order the messages will arrive -- that's under the control of the program that is using the object. So, when you design and code an object, its very much like writing an event-driven program: You use variables to keep track of the object state, and you must be prepared to handle messages as they arrive. So writing a class that handles events is really not much different than writing any other class.


David Eck, 3 April 2006