Chapter 3
Object Orientation

Modified

Overview

Chapter 2 presented a first look at Java source code and details on fields, constructors, parameters, methods, assignment and conditional statements. Here we will examine fundamental problem solving approaches of modularization and abstraction.

3.1 The clock example

A 24-hour clock displays time in hours:minutes format from 00:00 (midnight) to 23:59 (one minute before midnight).

Exercise 1 - Clock example

In BlueJ

  1. Open project chapter03\clock-display.

     

  2. Create a NumberDisplay object with rollOverLimit = 3.
    • Inspect the object but don't close.
    • Call increment() method at least 6 times.
    • What behavior does a NumberDisplay object exhibit?

       

  3. Create a ClockDisplay object with hour=23 and minute = 58.
    • Inspect the object but don't close.
    • Call timeTick() method at least 3 times.
    • Notice the displayString field. What behavior does a ClockDisplay object exhibit?

 

3.2 Abstraction and modulation

Abstraction is the standard means humans use to handle complexity, we learn to ignore most details. Consider the chair on which you are setting. A chair implementation is the modules:

We use the chair as an abstraction of these parts, ignoring the implementation details when set down. The details of the chair are important for understanding how chairs are implemented but not needed to use a chair.

Modularization is somewhat the complement of abstraction. It is the standard means humans use to divide complex details into smaller, simpler and related components. Consider again the chair on which you are setting.

To implement a chair we first divide the chair abstraction into smaller modules, for example the seat. We may then divide the seat into smaller modules, the padding and support. We can divide the padding into foam rubber and clothe modules. Eventually we divide modules to its simplest level. We can then focus on implementing each module separate of the others; the foam rubber module can be made separate from the clothe module.

Modularization divides the whole into related detail groups; abstraction combines the details into a view of the whole.

 

3.3 Abstraction in software

You have already seen that seemingly simple software has considerable complexity. Designing correct software is hard primarily due to the large number of details that must each be correct. Abstraction allows us to think about  details as a group.

Recall the TicketMachine method printTicket, the details are listed below. We abstract or ignore the details and think only that printTicket method prints a ticket not about each println statement or the syntax.

 public void printTicket()
 {
       System.out.println("##################");
       System.out.println("# The BlueJ Line");
       System.out.println("# Ticket");
       System.out.println("# " + price + " cents.");
       System.out.println("##################");
       System.out.println();

       total += balance;
       balance = 0;
 }

 

3.4 Modularization in the clock example

Abstraction ignores the detail of the number range difference between hour (00-23) and minute (00-59) module using a variable maximum number range. The hour maximum is 23 and the minute maximum is 59 is the only difference.

From this brief analysis, we see the clock display has 2 number displays for hours and minutes.

 

3.5 Implementing the clock display

The number display class needs two fields for the state of a NumberDisplay object:

 public class NumberDisplay
 {
 private int limit;
 private int value;
 Constructor and methods omitted
 }

 

The abstract clock display has 2 number displays for hours and minutes.

The real clock display needs two fields for the state of a ClockDisplay object:

 public class ClockDisplay
 {
 private NumberDisplay hours;
 private NumberDisplay minutes;
 Constructor and methods omitted
 }

 

3.6 Class diagrams versus object diagrams

Static view - The class diagram at right shows the class definition relationships. ClockDisplay depends on the NumberDisplay.

 

Exercise 2 - Class diagrams and object diagrams
  1. Sketch the static Class diagram for the Exercise2A class below.
    • Show any dependency arrows.

       

  2. Sketch the dynamic Object diagram for the person object below after execution of:
      • Exercise2A person = new Exercise2A("John", "Crab");
    • Show reference arrows.

     

  3. Sketch the Class diagram for the Exercise2B class below.
    • Show any dependency arrows.

     

  4. Sketch the Object diagram for the couple object below after execution of:
      • Exercise2B couple = new Exercise2B();
    • Show reference arrows.
 public class Exercise2A
 {
 private String name;
 private String favoriteFood;
 public Exercise2A(String newName, String food) {
      favoriteFood = food;
      name = newName;
 }
 }
 public class Exercise2B
 {
 private Exercise2A husband;
 private Exercise2A wife;
 private Exercise2A child;
 public Exercise2B( ) {
      husband = new Exercise2A("John", "Crab");
      wife = new Exercise2A("Sally", "tripe");
      child = new Exercise2A("Kido", "dirt");
 }
 }

 

3.7 Primitive types and object types


3.8 The ClockDisplay source code

3.8.1 Class NumberDisplay

Logic operators - Operate on boolean (true or false) to produce a boolean result.
Truth tables - Define boolean operations.

! - not. Examples: !true is false, !false is true.

 

&& - and. Result true when both operands are true.

 

|| - or. Result true when either operand is true

A  B A || B
false false false
false true true
true false true
true true true
Exercise 3 - Logical operators
  1. What is the result of the following?
    1. true && false
    2. false || true
    3. true && (false || true)
    4. !true || false && true
    5. (4 < 5)
    6. (4 < 5) && (6 >= 5)
    7. (4 > 5) || (6 <= 5)
    8. if ( (4 > 5) || (6 <= 5) ) System.out.println( "NOT Done");
    9. if ( (4 < 5) && (6 >= 5) ) System.out.println( "Done");

 

 NumberDisplay Source code

 public class NumberDisplay
 {
 private int limit;
 private int value;
  public NumberDisplay(int rollOverLimit)
 {
     limit = rollOverLimit;
     value = 0;
 }
  public int getValue()
 {
     return value;
 }
  public String getDisplayValue()
 {
     if(value < 10)
          return "0" + value;
     else
          return "" + value;
 }
  public void setValue(int replacementValue)
 {
     if((replacementValue >= 0) && (replacementValue < limit))
          value = replacementValue;
 }
  public void increment()
 {
     value = (value + 1) % limit;
 }
 }
Exercise 3 - Class NumberDisplay Analysis

In BlueJ

  1. Create a new NumberDisplay object named miles with a rollOverLimit of 5.
    • What is the state of miles?

     

  2. Set the object miles to 7 using method setValue.
    • What is the new state of miles?
    • What happened in setValue?
       
  3. Open the Editor on NumberDisplay and examine setValue method. Would the following change how setValue behaved? Try it.

    if((replacementValue >= 0) || (replacementValue < limit))
        value = replacementValue;

In your head

  1. Give the Java code to set the object miles to 4 using method setValue.
    • What is the new state of miles?

     

  2. Give the Java code to increment the object miles one time.
    • What is the new state of miles?


 

3.8.2 String Concatenation

Concatenation operator - + with one String operand results in a concatenated String.
Exercise 3.5 - Concatenation

In your head

  1. 1+3
     
  2. "1"+3
     
  3. (1+3)+"a"

 

 public String getDisplayValue()
 {
     if(value < 10)
          return "0" + value;
     else
          return "" + value;
 }

 

 public int getValue()
 {
     return value;
 }
Exercise 4 - getDisplayValue() Analysis

In your head

  1. For value = 5,  what is: "0" + value
     
  2. For value = 5,  what is: "" + value
     
  3. Assume NumberDisplay object miles has state:
  4. limit = 10
    value = 5

    What is: miles.getDisplayValue();

  5. Assume NumberDisplay object miles has state:

    limit = 120
    value = 105

    What is: miles.getDisplayValue();

  6. Use System.out.println and getDisplayValue to print the value of miles.

     

  7. What is the difference between the signature of methods getValue and getDisplayValue?


 

3.8.3 The modulo operator

Modulo operator     % is the remainder of division.
 
Division operator     / is the quotient of division.
  public void increment()
 {
     value = (value + 1) % limit;
 }
Exercise 5 - increment() Analysis

In your head

  1. 45 / 5
     
  2. 45 % 5
     
  3. 13 / 2
     
  4. 13 % 2
     
  5. (12 + 1) % 2
     
  6. For n=0, 1, 2, 3, 4, 5, 6, ... What are all the possible results of:

    n % 4

  7. For n=0, 1, 2, 3, 4, 5, 6, ... What are all the possible results of:

    n % m

    where m is any integer.

  8. Assume NumberDisplay object miles has state:

limit = 7
value = 5

What is: miles.increment();

  1. Assume NumberDisplay object miles has state:

limit = 7
value = 6

What is: miles.increment();

  1. Rewrite value = (value + 1) % limit using an if-statement.

 
 

3.8.4 Class ClockDisplay

 public class ClockDisplay
 {
 private NumberDisplay  hours;
 private NumberDisplay  minutes;
 private String               displayString;
 public ClockDisplay()
 {
     hours = new NumberDisplay(24);
     minutes = new NumberDisplay(60);
     updateDisplay();
 }
 public ClockDisplay(int hour, int minute)
 {
     hours = new NumberDisplay(24);
     minutes = new NumberDisplay(60);
     setTime(hour, minute);
 }
 public void timeTick()
 {
     minutes.increment();
     if(minutes.getValue() == 0) {
          hours.increment();
     }
     updateDisplay();
 }
 public void setTime(int hour, int minute)
 {
     hours.setValue(hour);
     minutes.setValue(minute);
     updateDisplay();
 }
 public String getTime()
 {
     return displayString;
 }
 private void updateDisplay()
 {
     displayString = hours.getDisplayValue() + ":" + minutes.getDisplayValue();
 }
 }
Exercise 6 - ClockDisplay Analysis

In BlueJ

  1. Open project chapter03\clock-display.
     
  2. Create a ClockDisplay object with time at 23:58.
    • Inspect the object but don't close.
    • Call each method.
    • Test that the clock display rolls over both the hours and minutes correctly.
       
  3. Create a ClockDisplay object that corresponds to the object diagram at right.
    • Inspect the object to verify.
      • Inspect the hours.
      • Inspect the minutes.
    • What is the correspondence of the two NumberDisplays with the displayString field?


 

3.9 Objects creating objects

 public class NumberDisplay
 {
 private int limit;
 private int value;
  public NumberDisplay( int rollOverLimit )
 {
     limit = rollOverLimit;
     value = 0;
 }
 }
 public class ClockDisplay
 {
 private NumberDisplay hours;
 private NumberDisplay minutes;
  public ClockDisplay()
 {
     hours = new NumberDisplay( 24 );
     minutes = new NumberDisplay( 60 );
     updateDisplay();
 }
 }
Exercise 7 - Objects creating objects

In your head

  • Match each of the Java code below with one of the objects created at right.

     
  1. new ClockDisplay( );
     
  2. hours = new NumberDisplay( 24 );
     
  3. minutes = new NumberDisplay( 60 );
     
  4. What would change for a twelve hour clock?
     
  5. Follow the Java code above as it executes:
  public ClockDisplay()
 {
     hours = new NumberDisplay( 24 );
     minutes = new NumberDisplay( 60 );
 }

 


 

3.10 Multiple constructors

Overloading - When more than one constructor (or method) have the same name. The signature and call are matched to determine which is called.
 public class ClockDisplay
 {
 private NumberDisplay hours;
 private NumberDisplay minutes;
 private String               displayString;
  public ClockDisplay()
 {
     hours = new NumberDisplay(24);
     minutes = new NumberDisplay(60);
     updateDisplay();
 }
  public ClockDisplay(int hour, int minute)
 {
     hours = new NumberDisplay(24);
     minutes = new NumberDisplay(60);
     setTime(hour, minute);
 }
  public void setTime(int hour, int minute)
 {
     hours.setValue(hour);
     minutes.setValue(minute);
     updateDisplay();
 }
 }
 public class NumberDisplay
 {
 private int limit;
 private int value;
  public NumberDisplay(int rollOverLimit)
 {
     limit = rollOverLimit;
     value = 0;
 }
  public void setValue(int replacementValue)
 {
     if((replacementValue >= 0) &&
        (replacementValue < limit))
          value = replacementValue;
 }
 }
Exercise 8 - Multiple constructors
  • Draw the dynamic Object diagram as you follow the Java code above as it executes:

ClockDisplay myDisplay = new ClockDisplay();

  • Match the objects created below with the corresponding Java code. The signature must match the call:
  1. ClockDisplay myDisplay = new ClockDisplay();
     
  2. ClockDisplay myDisplay = new ClockDisplay(15, 23 );
     
  3. ClockDisplay myDisplay = new ClockDisplay(24, 60);


3.11 Method calls

3.11.1 Internal method calls

Internal method call - Calling a method defined within the class from a constructor or method defined within the same class. The current object is used.

 

3.11.2 External method calls

External method call - Calling a method defined within a different class. The dotted object is used.
 public void setTime(int hour, int minute)
 {
     hours.setValue(hour);
     minutes.setValue(minute);
     updateDisplay();
 }
 public class ClockDisplay
 {
 private NumberDisplay  hours;
 private NumberDisplay  minutes;
 private String               displayString;
  public ClockDisplay()
 {
     hours = new NumberDisplay(24);
     minutes = new NumberDisplay(60);
     updateDisplay();
 }
  public ClockDisplay(int hour, int minute)
 {
     hours = new NumberDisplay(24);
     minutes = new NumberDisplay(60);
     setTime(hour, minute);
 }
  public void timeTick()
 {
     minutes.increment();
     if( minutes.getValue() == 0) {
          hours.increment();
     }
     updateDisplay();
 }
  public void setTime(int hour, int minute)
 {
     hours.setValue(hour);
     minutes.setValue(minute);
     updateDisplay();
 }
  private void updateDisplay()
 {
     displayString = hours.getDisplayValue() + ":" + minutes.getDisplayValue();
 }
 }
Exercise 8 - Internal and External method calls
  • Categorize each method call of ClockDisplay as internal or external.
    • Example of an external method call:

      hours.setValue(hour);

       

    • Example of an internal method call:

      updateDisplay( );


3.11.3 Summary of the clock display

Abstraction:

Exercise 9

In BlueJ

  • Change ClockDisplay (not NumberDisplay) to display a 12 hour clock rather than a 24 hour clock.
     
    1. Modify the ClockDisplay constructors to a 12 hour NumberDisplay object.
       
    2. Modify updateDisplay method to display hour 12 when the object hours value is 0.
       
      • Hint: Use an if-else statement with hours.getValue() to get and test the hours integer value.
         
  • Test appropriately to verify that values of object hours are displayed as 1-12 only.
 public class NumberDisplay {
   private int value;

   public int getValue()
   {
     return value;
   }

 


3.11.4 Using a debugger

Debugger - Tool for examining a program state (variables and field values) and statements as it executes.

 

3.11.4.1 Setting breakpoints

Exercise 9.1 - Breakpoints

In BlueJ

  1. Create a ClockDisplay instance with hour=11 and minute=58.
     
  2. Set a breakpoint in ClockDisplay method timeTick.
     
    1. Open the editor for the ClockDisplay class.
       
    2. Click on the line to breakpoint, the statement:

            minutes.increment();

       
    3. In the BlueJ menu, click Tools | Set/Clear Breakpoint.
       
  3. Call ClockDisplay method timeTick. The debugger should highlight the first breakpointed statement encountered in the program.
     
  4. What are the names of the instance variables (or fields) of a ClockDisplay object. See the Debugger window below.
     
  5. Double-click the minutes field to inspect. What is the value?
     
  6. Keep the Debugger open.

 

 

3.11.4.2 Single stepping

Exercise 9.2 - Single stepping

In BlueJ

  1. minutes.increment(); should still be highlighted in the Debugger window.
  2. Click Step in Debugger to execute the minutes.increment(); statement.
     
  3. What changed in the Debugger?
     
  4. Examine the minutes field in the Inspector. What changed?
     
  5. Click Step in Debugger to execute the if-statement.
    • Which statement was executed?
    • Why?
       
  6. Click Continue to complete the method timeTick.
Exercise 9.3 - Single stepping

In BlueJ

  1. Call ClockDisplay method timeTick again. The debugger should again highlight the first break-pointed statement encountered in the program.
     
  2. What is the statement at the breakpoint again?
     
  3. Inspect the hours field. What is the value?
     
  4. Inspect the minutes field. What is the value?
     
  5. Click Step in Debugger to execute one statement.
     
  6. Inspect the hours field. What is the value?
     
  7. Inspect the minutes field. What is the value?
     
  8. Click Step in Debugger to execute the if-statement.
    • Which statement was executed?
    • Why?
       
  9. Click Continue to complete the method timeTick.

 

3.11.4.3 Stepping into methods

executes one statement but will not follow the execution of a method.

executes one statement but follows the execution of a method.

Exercise 9.4 - Single stepping into methods

In BlueJ

  1. Set a breakpoint at the first statement of method setTime.
     
  2. Call method setTime with hour=23 and minute=59. The debugger should highlight the first break-pointed statement encountered in the program.
     
  3. What local variables (or parameters) are listed?
  4. Click Step to execute until the statement below is highlighted:
    •  
    • updateDisplay();
    •  
  5. Click Step Into to execute into the updateDisplay method.
  6. Click Step to follow the execution.
     
  7. Does the updateDisplay method return to the point following where it was called in setTime?


3.12 Another example of object interaction

3.12.1 The mail system example

Exercise 10
  • What are the static dependencies shown by the class diagram?

In BlueJ

  1. Experiment with the chapter03\mail-system project.
    1. Open the mail-system project.
       
    2. Create a MailServer object.
       
    3. Create two MailClient objects:
      1. name the two objects sophie and juan.
      2. supply each the MailServer object name just created
      3. give a user name that matches the object's name (i.e. "Sophie" and "Juan").
         
    4. Use the MailClient objects to send and receive messages using:
      1. sendMessage
      2. getNextMailItem or printNextMailItem
         
  2. Sketch the object diagram from part 1 similar to the ClockDisplay.


3.12.2 The this keyword


3.13 Using a debugger

3.13.1 Setting breakpoints

 

Exercise 11 - Breakpoints

In BlueJ

  1. Use sophie's sendMessage to send a message from "Sophie" to "Juan".
     
  2. Don't read the message yet.
     
  3. Set a breakpoint in MailClient method printNextMailItem.
    1. Open the editor for the MailClient class and set a breakpoint at the first line of method printNextMailItem.
    2. Click on the line to breakpoint.
    3. In the BlueJ menu, click Tools | Set/Clear Breakpoint.
       
  4. Call MailClient method printNextMailItem on juan. The debugger should highlight the first breakpointed statement encountered in the program.
     
  5. What are the names of the instance variables (or fields) of a MailClient object. See the Debugger window below.


3.13.2 Single stepping

Exercise 11 - Single stepping

In BlueJ

  1. Note there are no local variables listed in the Debugger window.
     
  2. What does the statement do at the breakpoint?
    •  
    • MailItem item = server.getNextMailItem(user);
    •  
  3. Click Step in Debugger to execute the statement.
     
  4. What changed in the Debugger?
     
  5. item is a local variable and references the MailItem object for user "Juan".
    1. Since "Juan" has mail, which statement would you expect the if-statement to execute next?
       
    2. Is the value of item listed as null or something else?
       
  6. Click Step in Debugger to execute the statement.
    • Which statement was executed?
    • Why?

Click Continue to complete the method printNextMailItem.

Exercise 12 - Single stepping

In BlueJ

  1. Call MailClient method printNextMailItem on juan. The debugger should highlight the first breakpointed statement encountered in the program.
     
  2. Is the statement at the breakpoint again?

    MailItem item = server.getNextMailItem(user);

     

  3. Click Step in Debugger to execute the statement.
     
  4. item is a local variable and references the MailItem object for what user?
    1. Since "Juan" has mail, which statement would you expect the if-statement to execute next?
    2. Is the value of item listed as null?
       
  5. Click Step in Debugger to execute the statement.
    • Which statement was executed?
    • Why?

Click Continue to complete the method printNextMailItem.

 

3.13.3 Stepping into methods

executes one statement but will not follow the execution of a method.

executes one statement but follows the execution of a method.

Exercise 13 - Single stepping into methods

In BlueJ

  1. The breakpoint should still be set in method printNextMailItem.
     
  2. Use sophie's sendMessage to send a message from "Sophie" to "Juan".
     
  3. Don't read the message yet.
     
  4. Call MailClient method printNextMailItem on juan. The debugger should highlight the first breakpointed statement encountered in the program.
     
  5. What is the variable item?
     
  6. Click Step to execute until the statement below is highlighted:

    item.print();

  7. Click Step Into to execute into the print method.
     
  8. Continue to click Step Into to follow the execution.

 

3.14 Method calling revisited

Exercise 14 - Method calling revisited

In BlueJ

  1. Set a breakpoint in the first statement of method sendMessage:

    MailItem mess = new MailItem(user, to, message);

     

  2. Use sophie's sendMessage to send a message from "Sophie" to "Juan".
     
  3. What are the formal parameters (i.e. local variables) listed?
     
  4. Click Step to execute new MailItem(user, to, message) method.
     
  5. What changed and why?
     
  6. Click Continue to complete the execution.
     
  7. Use juan's sendMessage to send a message from "Juan" to "Sophie".
    • Repeat 3-6 again.

3.15 Summary