JMU JMU - Department of Computer Science
Lab: Experimenting with Polymorphism through Interfaces


Instructions: Answer as many of the following questions as you can during the lab period. If you are unable to complete the assignment during the lab period it is strongly recommended that you complete it on your own.

Getting Ready: Before going any further, you should:

  1. Make a directory for this lab.
  2. Setup your development environment.
  3. Download the following files which are contained in this zip file, lab-d5.zip,
    Dukulator.java
    DukulatorWindow.class
    IntegerCalculator.java
    ExpressionObserver.java
    dukulator.gif
    Taxable.java
    Account.java
    AccountDriver.java
    ControllableAlarmClock.class
    ClockDriver.java
    change.gif
    clock.gif
    down.gif
    up.gif
    AlarmController.java
    worksheet.txt <<<----------Download this one from here. It is not in the zip file.
    to your working directory.

1. Making a Class Polymorphic using an Interface: This part of the lab will help you understand one of the important uses of interfaces (and the importance of polymorphism).
  1. Open the source code for the Dukulator class.
  2. Compile, execute and test the Dukulator class. (Note: You should execute the application from the command line.)
  3. What aspects of the Dukulator did not work properly?
  4. Open the source code for the ExpressionObserver interface and the IntegerCalculator class.
  5. As you can see, an ExpressionObserver is an object that knows how to evaluate a String representation of an expression and return a String representation of the result. Add a "clause" to the declaration of the IntegerCalculator class so that it claims to implement this interface.
  6. What "clause" did you add?
  7. Add a method to the IntegerCalculator class so that it actually does implement the ExpressionObserver interface. This method must use the calculate() method and must return the String "Error" if the calculate() method throws an exception or the String representing the value of the expression if there is no errer.
  8. What code did you add?
  9. The DukulatorWindow is a GUI window that contains a "soft" numeric keypad and a one-line display. Familiarize yourself with the behavior of this class by reading the descriptions of the following methods:
        /**
         * Default Constructor
         */
        public DukulatorWindow()
    
    
    
        /**
         * Set the ExpressionObserver that should be notified when
         * the = button is pressed
         *
         * @param observer   The observer to notify
         */
        public void setExpressionObserver(ExpressionObserver observer)
        
  10. Since your IntegerCalculator class is now an ExpressionObserver you can now tell a DukulatorWindow object to call your IntegerCalculator when the = button is pressed.

    Modify the Dukulator class so that it constructs an IntegerCalculator and associates it with the DukulatorWindow.

  11. What code did you add?
  12. Compile, execute, and test the Dukulator class. (Note: You should execute the application from the command line.)
  13. Did it work properly?
  14. How did polymorphism come into play in this example?
2. Polymorphism, Overloading and Parameters: This part of the lab will help you gain a better understanding of passing polymorphic objects to overloaded methods.
  1. Open and read Taxable, AccountDriver, and Account.
  2. What overloaded methods are in AccountDriver?
  3. Compile AccountDriver.
  4. barney is declared to be a Comparable but instantiated as an Account, and wilma is declared to be a Taxable but instantiated as an Account. Why does AccountDriver compile without errors?
  5. In the main() method of AccountDriver, after the initialization statements, add a call to summarize() passing it the object named barney.
  6. What code did you add?
  7. Compile and execute AccountDriver.
  8. What output was generated?
  9. Why was this output generated?
  10. Comment-out the summarize() method that is passed an Account object.
  11. Compile AccountDriver.
  12. What error was generated?
  13. Why was this error generated?
  14. Remove the comments from the summarize() method that is passed an Account object. (That is, the AccountDriver class should again have three summarize() methods.
  15. Modify the call to summarize() so that it now passes fred instead of barney.
  16. What does that statement look like after the modification?
  17. Compile and execute AccountDriver.
  18. What output was generated?
  19. Why was this output generated?
3. Interfaces, Polymorphism, and GUIs: This part of the lab will help you learn how to use interfaces and polymorphism to build classes that contain the "application logic" for GUI-based applications.
  1. Open the source code for the ClockDriver class.
  2. Compile, execute (from the command line) and test the ClockDriver class. (Note: The information at the bottom of the clock shows the state of the alarm settings. The buttons/checkbox are for changing the alarm settings.)
  3. What aspects of the clock did not work properly?
  4. The ControllableAlarmClock is a GUI window that contains a "displays" and "controls" for an alarm clock. Familiarize yourself with the behavior of this class by reading the descriptions of the following methods:
        /**
         * Default Constructor
         *
         * Construct an AlarmClock for your "home" city
         */
        public ControllableAlarmClock()
    
    
    
        /**
         * Explicit Value Constuctor
         *
         * Construct an AlarmClock for the given city
         * (Note: Not all city names are recognized)
         */
        public ControllableAlarmClock(String city)
    
    
    
    
    
    
        /**
         * Add an ActionListener to the buttons on the alarm setter
         *
         * @param listener   The ActionListener
         */
        public void addActionListener(ActionListener listener)
    
    
    
        
    
        /**
         * Get the AMPM setting on the alarm
         *
         * @return   "AM" or "PM"
         */
        public String getAlarmAMPM()
        
    
    
    
        /**
         * Get the hour setting on the alarm
         *
         * @return   The hour setting on the
         */
        public int getAlarmHour()
    
    
        /**
         * Get the minute setting on the alarm
         *
         * @return   The minute setting on the
         */
        public int getAlarmMinute()
    
    
    
        /**
         * Is the alarm on?
         *
         * Note: This method does not check to see if the alarm is currently
         * beeping.  It checks to see if the alarm will beep when at
         * the appropriate time
         *
         * @return true if the alarm is currently on; false otherwise
         */
        public boolean isAlarmOn()
    
    
    
        /**
         * Set the hour of the alarm
         *
         * @param hour     The hour of the alarm
         */
        public void setAlarmHour(int hour)
    
    
    
        /**
         * Set the minute of the alarm
         *
         * @param minute   The minute of the alarm
         */
        public void setAlarmMinute(int minute)
    
    
    
        /**
         * Set the AM/PM of the alarm
         *
         * @param ampm     "AM" for before noon, "PM" for noon and after
         */
        public void setAlarmAMPM(String ampm)
    
    
    
        /**
         * Turn the alarm off
         */
        public void turnAlarmOff()
    
    
    
        /**
         * Turn the alarm on
         */
        public void turnAlarmOn()
    
        
  5. Familiarize yourself with the ActionListener java.awt.event.ActionListener interface. (This interface is part of the Java library that is used to develop graphical user interfaces. It has one method, actionPerformed(). This method is called when buttons/checkboxes are pressed.)
  6. Familiarize yourself with the ActionEvent.getActionCommand() java.awt.event.ActionEvent#getActionCommand() method in the java.awt.event.ActionEvent class. (This class is also part of the Java library that is used to develop graphical user interfaces. This method returns a String that can be used to identify the button/checkbox that was pressed.)
  7. Modify the actionPerformed method in the AlarmController class so that it prints the String description of the button/checkbox that was pressed. (Note: At this point, the AlaramController will not respond to buttons/checkboxes. You'll fix that shortly.)
  8. What code did you add?
  9. Modify the ClockDriver class. It must now also:
    • Declare an AlarmController object named controller.
    • Construct controller (passing the constructor clock).
    • Call the clock object's addActionListener() method, passing it controller.
  10. What code did you add?
  11. Compile and execute the ClockDriver class. (Note: You should execute the application from the command line.)
  12. What String is associated with each button/checkbox in the ControllableAlarmClock?
  13. Add the following code to the the actionPerformed method in the AlarmController class:
           int      value;
    
    
           if      (ac.equals("HOUR_DOWN"))
           {
              value = clock.getAlarmHour();
              value--;
              if (value < 1) value = 12;          
              clock.setAlarmHour(value);          
           }
           else if (ac.equals("HOUR_UP"))
           {
              value = clock.getAlarmHour();
              value++;
              if (value > 12) value = 1;          
              clock.setAlarmHour(value);          
           }
        
  14. Compile the AlarmController class and execute and test the ClockDriver class. (Note: You should execute the application from the command line.)
  15. What works and what doesn't?
  16. Modify the actionPerformed() method in the AlarmController class so that everything works properly.
  17. What code did you add?

Copyright 2011