CPSC 124, Fall 1996

Second Test


This is the second test given in CPSC 124: Introductory Programming, Fall 1996. See the information page for that course for more information.

The answers given here are sample answers that would receive full credit. However, they are not necessarily the only correct answers.


Question 1: Define the following terms, as they relate to this course:

a) Reference to an object

Answer: A reference to an object is just the address of that object in memory. A variable can never hold an object, only a reference to an object. The object itself is stored on the heap. A reference acts as a "pointer" to the object, which can be used to find the object when necessary.

b) Subclass

A subclass is a class that extends (or is based on) another class, which is called its superclass. The subclass inherits all the behaviors and properties of the class. It can then add to or modify the inherited behaviors.

Answer:

c) Polymorphism

Answer: Polymorphism refers to the fact that different objects can respond to the same method in different ways, depending on the actual type of the object. This can occur because a method can be overridden in a subclass. In that case, objects belonging to the subclass will respond to the method differently from objects belonging to the superclass.

(Note: If B is a subclass of A, then a variable of type A can refer to either an object of type A or an object of type B. Let's say that var is such a variable and that action() is a method in class A that is redefined in class B. Consider the statement "var.action()". Does this execute the method from class A or the method from class B? The answer is that there is no way to tell! The answer depends on what type of object var refers to, a class A object or a class B object. The method executed by var.action() depends on the actual type of the object that var refers to, not on the type of the variable var. This is the real meaning of polymorphism.)

d) this (when used in a method in a Java program)

Answer: When used in the definition of an instance method, this refers to the object to which the method belongs. Think of calling an instance method as sending a message to an object. Then this refers to the object that received the message.


Question 2: What is the relationship between "classes" and "objects"? What is the difference between them?

Answer: A class is used as a template for making objects. That is, a class contains information about what sort of data an object should contain and what sort of behaviors an object should have. One class can be used to make many objects. All the objects have the same behavior, as specified by the class, and they all hold the same kind of instance variables (although the data stored in those instance variables can be different from one object to another).

Classes and objects are totally different sorts of things! Objects do not exist until they are created, after a program is running, and they are destroyed before the program ends. A class is actually part of the program, so of course it exists the whole time a program is running. If you have a class, you can create a subclass based on that class, but you can't do anything similar with an object.


Question 3: Write a subroutine named middle with three parameters of type int. The subroutine should return the middle number among its three parameters, in order of size. For example, middle(3,17,12) would have the value 12; middle(737,-33,1266) would have the value 737; and middle(42,42,42) would have the value 42.

Answer: There are many ways to write this subroutine. Here is the shortest:

          public static int middle(int x, int y, int z) {
             if ( x <= y && y <= z  ||  z <= y && y <= x )
                return y;  // y is in the middle
             if ( y <= x && x <= z  ||  z <= x && x <= y )
                return x;  // x is in the middle
             return z;  // it must be z that is in the middle
          }

You might find it easier to think about it this way: There are six different orders in which x, y, and z can occur. You can go through and check each possible order as one case in an if statement. So here is another way to write the subroutine:

          public static int middle(int x, int y, int z) {
             if ( x <= y && y <= z )
                return y;
             else if ( x <= z && z <= y )
                return z;
             else if ( y <= x && x <= z )
                return x;
             else if ( y <= z && z <= x )
                return z;
             else if ( z <= x && x <= y )
                return x;
             else // This is the case where z <= y && y <= x
                return z;
          }

(It might be worth noting that Java won't let you use else if on the last line instead of just else. The problem is that with else if, it looks like there is a possibility that this routine won't return any value at all, and Java won't let you write such a routine. Of course, you know that you've covered all the possibilities and that in fact some value will always be returned. But Java isn't smart enough to figure that out.)


Question 4: Suppose that you want a very simple class to represent the money in a bank account. It needs three methods, one to deposit a given amount into the account, one to withdraw a given amount, and one to check how much money is in the account. It also needs a constructor that creates an account containing a specified initial amount of money. The class should have one instance variable, for storing the amount of money in the account. Write a complete Java class satisfying this requirement.

Answer:

       public class BankAccount {
       
          protected double balance;   // amount of money in the account
          
          public BankAccount(double initialDeposit) {  // constructor
             balance = initialDeposit;
          }
          
          public void deposit(double amount) {
             balance = balance + amount;
          }
          
          public void withdraw(double amount) {
             balance = balance - amount;
          }
          
          public double checkBalance() {
             return balance;
          }
          
       }

Question 5: Draw the picture that will be produced by the following paint() method:

             public static void paint(Graphics g) {
                for (int i=10; i <= 210; i = i + 50)
                   for (int j = 10; i <= 210; j = j + 50)
                      g.drawLine(i,10,j,60);
             }

Answer: The outer loop is executed for values of i equal to 10, 60, 110, 160, and 210. For each of these values, the inner loop is executed for j equal to 10, 60, 110, 160, and 210. The drawLine is therefore executed 25 times -- and so, 25 different lines are drawn. These lines connect the five points (10,10), (60,10), (110,10), (160,10), and (210,10) to the five points (10,60), (60,60), (110,60), (160,60), and (210,60) in all possible pairings. Here is the picture:

(25 criss-crossed lines)


Question 6: Suppose that you are given a class named Sorter. An object of this class keeps a sorted list of numbers. When a new number is added, it is inserted into its correct place in the list. For example, if 17.42 is added to the list 3.4, 12.1, 19.96, 20.0, then the list will be modified to 3.4, 12.1, 17.42, 19.96, 20.0. The constructor in the Sorter class creates an initially empty list. The class includes the methods

          void add(double newNum)  -- adds a number to the list
          double get(int N)  -- returns the Nth number from the list

Write a complete Java program that uses a Sorter object to sort a list of 10 numbers entered by the user. The program should ask the user to enter 10 numbers. It should read each number and add it to the Sorter object. Then it should retrieve the numbers from the Sorter object in order and print out each number on the console.

Answer:

        public class TestSorter {
        
           public static void main(String[] args) {
           
              Console console = new Console();
              
              Sorter sort = new Sorter();   // create a Sorter object
              
              console.putln("Please enter 10 numbers:");
              
              for (int i = 0; i < 9; i++) {
                 console.put("? ");
                 double x = console.getlnDouble();    // read a number from the user...
                 sort.add(x);                         //   ...and add the number to the Sorter
              }
              
              console.putln();
              console.putln("The numbers in sorted order are: ");
              
              for (int i = 0; i < 9; i++) {
                 double num = sort.get(i);    // get the i-th number from the sorter...
                 console.putln(num);            //   ...and print it out to the console
              }
              
              console.close();
              
           }  // end of main()
           
        }  // end of class TestSorter

Question 7: Programs written for a graphical user interface have to deal with "events." Explain what is meant by the term "events." Give at least two different examples of events, and discuss how a program might respond to those events.

Answer: An event is anything that can occur asynchronously, not under the control of the program, to which the program might want to respond. GUI programs are said to be "event-driven" because for the most part, such programs simply wait for events and respond to them when they occur. In many (but not all) cases, an event is the result of a user action, such as when the user clicks the mouse button on a canvas, types a character, clicks a button, or makes a selection from a pop-up menu. The program might respond to a mouse-click on a canvas by drawing a figure, to a typed character by adding the character to an input box, or to a click on a button by clearing the canvas. More generally, a programmer can set up any desired response to an event by writing an event-handling routine for that event.


Question 8: One of the big problems in software development is the "reuse problem." That is, how can pieces of programs that have already been written be reused in other projects, in order to avoid duplication of effort. Discuss how object-oriented programming in general, and inheritance in particular, can help to solve the software reuse problem. An example would be helpful.

Answer: Reuse is desirable because developing new software is very expensive, so any opportunity to cut down on the size of the job by reusing previous work is a good thing. However, reusing old software can itself be difficult. In object-oriented programming, a class is designed from the beginning to be reusable. The same class can be used over and over in projects that require the same capabilities. More important, inheritance makes it possible to customize a class to a particular project without going into the class itself and modifying its source code (and possibly introducing new errors into the class in the process). All you have to do is make a subclass and put any additions and modifications that you need in the subclass.


Question 9: Object-oriented programming means more than just using objects and classes in a program. It also means applying object-oriented ideas to the analysis of problems and the design of programs. Explain briefly how object-oriented analysis and design would work. What is the process used? What is the goal?

Answer: The goal of object-oriented analysis and design is to produce a set of classes and objects that can be used to solve the problem under consideration. The basic idea is simple: Identify concepts that are involved in the problem, and create classes to represent those concepts. Then identify behaviors that the objects in the program will need, and write methods to provide those behaviors. One way to approach the problem is to start with an English description of what the program is supposed to do. The nouns in this description are candidates to be classes or objects in the program. The verbs are candidates to be methods. You could then try to discover other classes and methods that you might need with a role-playing game, in which you see how the classes you've already designed will carry out their assigned tasks. As the role-playing proceeds, you are likely to find other classes and methods that you can add to your program.


David Eck