Chapter 2
Class Definitions

Modified

Overview

Chapter 1 presented the general concepts behind object oriented programming and the skills needed for creating and using objects from predefined classes. Here we will define and refine these concepts more precisely and in more detail. We will also examine how to take different actions dependent upon a condition being true or false.

2.1 Ticket machines

Train station ticket machines print a ticket when the correct money is inserted. We define a class that models a naive ticket machine where:

Exercise 1

In BlueJ

  1. Open project: Chapter02\naive-ticket-machine
  2. In BlueJ menu:
    • Click Compile
    • Click View
    • Check Show Terminal.
  3. In Terminal Window:
    • Click Options
    • Check Record method calls.
  4. Create an instance of the class using TicketMachine(ticketCost) constructor.
    • Supply an int parameter for the ticketCost in cents for $1.00.
  5. Complete Exercise 2.1-2.4 below.

    Exercise 2.1

    1. Try the getPrice method.
      • What does it do?
      • What is the return class?
    2. Insert some money and check the balance using methods:
      • insertMoney
      • getBalance
    3. Inspect the TicketMachine object.
    4. Insert more money than a ticket costs.
    5. Call method printTicket.

    Exercise 2.2

    • Check the balance.
    • Is that reasonable?

    Exercise 2.3

    • Experiment by inserting different amounts of money before calling printTicket method.
    • What is the balance after printTicket method is called?
    • What must happen to the balance field in printTicket method?

    Exercise 2.4

    • Experiment with the TicketMachine class before we examine it in detail.
    • Create another TicketMachine object with a different ticket price.
    • Buy and print a ticket without inserting any money (i.e. balance==0).
    • Does the ticket look much the same as before (i.e. valid)?
    • Is that reasonable behavior? Why or why not?


2.2 Examining a class definition

The TicketMachine class definition source code of the text with comments removed.

 public class TicketMachine
 {
 private int price;
 private int balance;
 private int total;
 public TicketMachine(int ticketCost)
 {
       price = ticketCost;
       balance = 0;
       total = 0;
 }
 public int getPrice()
 {
       return price;
 }
 public int getBalance()
 {
       return balance;
}
 public void insertMoney(int amount)
 {
       balance = balance + amount;
 }
 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 = total + balance;
       balance = 0;
 }
 }


2.3 Fields, constructors and methods

Exercise 2 - Understanding the TicketMachine class fields, constructors and methods

From the TicketMachine source listing above:

  1. What are the field names?
  2. What is the constructor name?
  3. What are the method names?
  4. Where does TicketMachine class begin and end?
  5. Can you give the beginning and ending of classes Picture, Circle, Student and LabClass?
  6. How do constructors and methods appear different?

 

2.3.1 Fields

Field definitions                 

 private int price;
 private int balance;
 private int total;
Object named ticketMachine_1,
an instance of TicketMachine class.
It corresponds to the field definitions.   

 

 


2.3.2 Constructors

TicketMachine Constructor                       

 public TicketMachine(int ticketCost)
 {
       price = ticketCost;
       balance = 0;
       total = 0;
 }

price = ticketCost;

  • Field price is assigned value of
    parameter ticketCost.

balance = 0;

  • Field balance is assigned value 0.

Object constructed by:     

 TicketMachine (43)
 

Inspecting fields after construction.

 

 


2.3.3 Passing data via parameters

 

public TicketMachine(int ticketCost) - Formal parameter is ticketCost.

 

TicketMachine( 43 ) - Actual parameter is 43.

 Passing actual parameter 43 to formal parameter ticketCost.


 

 


new TicketMachine( 43 )

 

The scope (where known) of formal parameter ticketCost is TicketMachine constructor.
 
 public TicketMachine(int ticketCost)
 {
       price = ticketCost;
       balance = 0;
       total = 0;
 }
      

The scope of field balance is TicketMachine constructor,  getBalance, insertMoney and all other TicketMachine methods.              

 private int price;
 private int balance;
 private int total;

 

 public int getBalance()
 {
       return balance;
}

 

 public void insertMoney(int amount)
 {
       balance = balance + amount;
 }

Generally, the scope of fields is the entire class, the scope of parameters is only the method. The field balance is known in all methods; the parameter amount is only know inside insertMoney.

 private int price;
 private int balance;
 private int total;
 
 public void insertMoney(  int amount)
 {
       balance = balance + amount;
 }

 

Exercise 3 - Formal Parameters, Fields and Scope
 private int price;
 private int balance;   
 private int total;
  public int getPrice()   
 {
       return price;
 }
 public void insertMoney(int amount)
 {
       balance = balance + amount;
 }
  1. What is the formal parameter of insertMoney method?
  2. What is the formal parameter of getPrice method?
  3. What is the scope of amount?
  4. What is the scope of balance?
  5. Can balance be used in method getPrice?
  6. Can amount be used in method getPrice?
  7. Try in BlueJ.
    • In method getPrice change return price; to return amount;
    • Compile.
    • What happened and why?

 

2.5 Assignment

int balance;       
balance = 40*3;                  
String name;
name = "Fred";                 
boolean onFire;
onFire = true;

For now, assume both sides must be the same data type: int, String, or boolean.

Exercise 3.5 - Assignment and Expressions
 
 int balance;                  String name;                  boolean onFire;

What are the values of the following?

  1. name = "Fred" + "Flintstone";
  2. onFire = true or false;
  3. balance = 40*3+2;
  4. balance = 40*3+2;
    balance = balance + 12;

Are the following valid syntax given the definitions above?

  1. balance = "Hello";
  2. name = 5;
  3. onFire = true;
  4. onFire = balance;

 

2.6 Accessor methods

The four methods of TicketMachine:

 private int price;
 private int balance;
 private int total;
 
 public int getPrice()
 {
       return price;
 }
 public int getBalance()
 {
       return balance;
}
 public void insertMoney(int amount)
 {
       balance = balance + amount;
 }
 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 = total + balance;
       balance = 0;
 }
/**
 * Return the price of a ticket.
 */
 
public int getPrice()
 
 {
       return price;
 }
  Comment
  Comment
  Comment

  Header or signature

  Body
  Body
  Body
/**
 * Receive amount of money in cents from a customer.
 */
 public void insertMoney(int amount)   
 {
       balance = balance + amount;
 }
Comment
Comment
Comment
Header or signature
Body
Body
Body
Exercise 4 - Methods
  1. How does the header of getPrice and insertMoney differ?
  2. How does the body of getPrice and insertMoney differ?
  3. Try in BlueJ.
    • Remove the return price; statement from getPrice.
    • Compile.
    • What happened and why?
  4. Write a new accessor method getTotal that returns the total field value.
    • Compile and test.

 

2.7 Mutator methods

Assignment changes a variable, such as a field. Calling method printTicket mutates the field balance = 0;

 
 public void insertMoney(int amount)   
 {
       balance = balance + amount;
 }
 
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 = total + balance;
        balance = 0;

 }

 

Exercise 5 - Mutators                                                               
  • In BlueJ:
    • Create a TicketMachine object with a positive ticket price.
    • Inspect the object doing the following calls:
      1. Call insertMoney method on the object, inserting 53 cents.
      2. Call insertMoney method on the object, inserting 47 cents. Is insertMoney a mutator or accessor method?
      3. Call printTicket method on the object. Is printTicket a mutator or accessor method?
Exercise 6 - Assignment   
  1. What is the value of balance after each statement:

    balance = 40;
    balance = 20;
    balance = 10;
     

  2. What is the value of balance after each statement:

    balance = 40;
    balance = balance + 20;
    balance = balance + 10;

     

  3. What is the value of balance after each statement:

    balance = 40;
    balance += 20;
    balance += 10;    
             

  4. How can we tell from just the header that setPrice is a method and not a constructor?
  5. public void setPrice(int ticketCost)

  6. Complete the body of setPrice so that it assigns the parameter value to the price field. Enter in BlueJ and test.
  7. Is setPrice a mutator or accessor?

 

2.8 Printing from methods

Printing object ticketMachine_1

 
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 = total + balance;
       balance = 0;
 }
Terminal Window

##################
# The BlueJ Line
# Ticket
# 43 cents.
##################

 

  1. "abc"+"def" is "abcdef"
     
  2. "12"+3 is "123". The integer 3 is converted to a String "3" and then "12" +"3" is concatenated.
Exercise 7 - Printing and String Concatenation
  1. What is printed by the following?

    System.out.println("# The BlueJ Line");

  2. What is printed by the following when price is 54?

    System.out.println("# " + price + " cents.");

     

  3. What is the result of the following when price is 54?
    1.  "# " + price + " cents."
    2. "ab" + "c"
    3. 34 + 5
    4. "34"+"5"
    5. "34"+"5"
    6.  "# " +"price" + " cents."
    7.  "# + price + cents."

In BlueJ:

  1. Create a TicketMachine object having a price of 43 cents.
    • Inspect the object.
    • Call the printTicket method on the object.
       
  2. Add a method prompt to the TicketMachine class. The method has void return type and no parameters. The method body should print:

    Please insert the correct amount of money.

    Test that it works.
     

  3. Add a method showPrice to the TicketMachine class. The method has void return type and no parameters. The method body should print:

    The price of a ticket is xyz cents.

    where xyz is replaced by the value of price field when the method is called.

    Test that it works.

     

  4. Add a method showPrice to the TicketMachine class. The method has void return type and no parameters. The method body should print:

    The price of a ticket is xyz cents.

    Test that it works.

 

2.9 Summary of the naive ticket machine

Exercise 8 - Testing the TicketMachine

In BlueJ   

  1. Implement another TicketMachine constructor:
     
    • with no ticketCost parameter
       
    • price is fixed at 1000 cents
       
    • create a TicketMachine object using your new constructor.
       
    • create another TicketMachine object using the old constructor and an actual parameter for a ticket price of 54 cents.
       
    • Inspect both objects. You should have two inspector windows. Are there any differences between the two objects?
       
    • Call insertMoney method using both objects.
       
    • Call printTicket method using both objects. Are there any differences between the two objects?

In your head

  1. Why does the following version of getBalance not give the same results as the original?

    public int getBalance()
    {
        balance = 0;
        return balance;
    }

    What tests can you run to demonstrate that it does not?

     

  2. What happens if you try to compile the TicketMachine class with the following version of getBalance:

    public int getBalance()
    {
            return balance;
            balance = 0;
    }

    What do you know about return statements that explain why this version is incorrect?

 

2.10 Reflecting on the design of the ticket machine

  1. No check that enough money inserted to pay for ticket.
  2. No check that sensible amount of money inserted, can insert negative amounts of money.
  3. No check that ticket price of constructor is sensible.
  4. No refund when too much money inserted.

 

2.11 Making choices: the conditional statement

  1. Check that enough money inserted to pay for ticket.
  2. Check that sensible amount of money inserted, no negative amounts of money.
  3. No range check that ticket price of constructor is sensible.
  4. No refund when too much money inserted.
Exercise 9 - Conditionals    

In BlueJ: 

  1. Open the better-ticket-machine project.
  2. Create a TicketMachine object:
    • with a ticketPrice parameter of 25 cents.
  3. Inspect the object.
  4. Call insertMoney method with amount parameter of -45 cents.
    • What happened to the object state?
       
  5. Call insertMoney method with amount parameter of 5 cents.
    • What happened to the object state?
       
  6. Call printTicket method.
    • What happened to the object state?
    • Explain how total changed.
    • Explain how balance changed.
       
  7. Call insertMoney method with amount parameter of 50 cents.
    • What happened to the object state?
       
  8. Call printTicket method.
    • What happened to the object state?
    • Explain how total changed.
    • Explain how balance changed.


 

Exercise 10 - if else conditionals

What are the following results when:

  • amount = 54
  • balance = 10
  • correct = true
  1. true
     
  2. if  ( true ) { balance = 6; } else { balance = 7; }
     
  3. if  ( correct ) { balance = 6; } else { balance = 7; }
     
  4. 4 > 5
     
  5. if (4 > 5 ) { balance = 6; } else { balance = 7; }
     
  6. 4 <= 5
     
  7. if ( 4 <= 5) { balance = 6; } else { balance = 7; }
     
  8. amount > 50
     
  9. if  (amount > 50 ) { balance = 6; } else { balance = 7; }
     
  10. amount - 10 > 50
     
  11. if  (amount - 10 > 50 ) { balance = 6; } else { balance = 7; }
     
  12. if  (amount > 0 ) {
         balance = balance + amount;
    }  
    else {
         System.out.println( "Use a positive amount: " + amount );
    }

Changes to naive-ticket-machine to make the better-ticket-machine

 public class TicketMachine
 {
 public void insertMoney(int amount)
 {
        if(amount > 0) {
              balance = balance + amount;
       }
       else {
              System.out.println("Use a positive amount: " + amount);
       }

 }
 public void printTicket()
 {
        if(balance >= price) {
              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 = total + price;
              balance = balance - price;
       }
       else {
              System.out.println("You must insert at least: " + (price - balance) + " more cents.");
       }

 }
  public int refundBalance()
 {
       int amountToRefund;
       amountToRefund = balance;
       balance = 0;
       return amountToRefund;
 }
 }

 

2.12 A further conditional-statement example

See printTicket above.

Exercise 11 - printTicket
  • After a ticket has been printed, could the value of balance field ever be set to a negative value by subtracting price? Justify your answer.

 

2.13 Local variables

  public int refundBalance()
 {
       int amountToRefund;

       amountToRefund = balance;
       balance = 0;
       return amountToRefund;
 }
Exercise 12 - Local variables  

In BlueJ:

  1. Open the better-ticket-machine project.
     
  2. Create a TicketMachine object:
    • with a ticketPrice parameter of 25 cents.
       
  3. Inspect the object.
    • Is amountToRefund variable a field of the object?
       
  4. Call insertMoney method with amount parameter of 45 cents.
    • What happened to the object state?
       
  5. Call refundBalance method with Inspect window open.
    • What happened to the object state?
    • What value was returned?
       
  6. Add the second line to method printTicket:

    balance = balance - price;
    amountToRefund = 0;

    • Compile. What does the error message mean?
       
  7. Correct printTicket method by deleting the added line.
     
  8. Change the local variable definition in refundBalance to a comment as using // as follows:
    • // int amountToRefund;
       
  9. Compile TicketMachine.
    • Why is there an error message?
       
  10. What happens if you try to compile the TicketMachine class with the following version of refundBalance?

      public int refundBalance()
     {
           return balance;
           balance = 0;
     }

  11. Local variables are temporary. Each time a method is called, the local variables are created. When the method returns, the local variables are destroyed.

    What is printed by 4 calls to the method:

     public void Exercise11() {
         int count = 0;
         count = count + 1;
         System.out.println(count);
    }

 

2.14 Fields, parameters and local variables

Exercise 13 - Fields, parameters and local variables

In BlueJ:

    • Add a new TicketMachine method, emptyMachine, that models emptying the machine of money.
       
    • The method should return the value in total and set total to 0.
       
    • Create an TicketMachine object with a ticket price of 45 cents.
       
    • Inspect.
       
    • Call insertMoney method with 73 as the actual parameter.
       
    • Call printTicket method.
       
    • Call emptyMachine method to test.
       
  1. Is emptyMachine an accessor, mutator, or both?
     
  2. Rewrite printTicket method:
    • declare a local variable amountLeftToPay
       
    • initialize amountLeftToPay to the difference between price and balance
       
    • Rewrite the conditional to check amountLeftToPay <= 0
      • if true, print a ticket
      • else print an error message stating the amount still required
         
    • Create an object with a ticket cost of 45 cents.
       
    • Inspect.
       
    • Test both conditions:
      • Call insertMoney method with 44 as the actual parameter.
      • Call printTicket method. Was the result as expected?
      • How can the other condition be tested, when balance is sufficient? Test to verify.

 

2.15 Summary of the better ticket machine

 

2.16 Reviewing a familiar example

 public class Student
 {
    private String name;
    private String id;
    private int credits;

    public Student(String fullName, String studentID)
   {
        name = fullName;
        id = studentID;
        credits = 0;
    }

    public String getName()
    {
        return name;
    }

    public void changeName(String replacementName)
    {
        name = replacementName;
    }

    public String getStudentID()
    {
        return id;
    }

    public void addCredits(int additionalPoints)
    {
        credits += additionalPoints;
    }

    public int getCredits()
    {
        return credits;
    }

    public String getLoginName()
    {
        return name.substring(0,4) + id.substring(0,3);
    }

    public void print()
    {
        System.out.println(name + " (" + id + ")");
    }

 }

 

Exercise 14 - Review and String methods
  1. "01234567".substring(2,5) is the String "234". Assume the name field is "012345". What is:
     
    1. "01234567".substring(4,5)
       
    2. "01234567".substring(4,7)
       
    3. "01234567".substring(4,10)
       
    4. name.substring(0,3)
       
    5. name.substring(-1,3)
       
  2. "01234567".length() is the integer 8. Assume the name field is "012345". What is:
     
    1. "01234".length()
       
    2. "Harvey".length()
       
    3. name.length()
       
    4. "01234".substring(1,4).length()
       
    5. name.substring(0,5).length()

In BlueJ:

  1. Open project chapter01\lab-classes
    • Examine in the editor.
       
  2. Student class contains how many:
    • fields
    • constructors
    • mutators
    • accessors
       
  3. What do the accessor names have in common?
     
  4. What would be returned by getLoginName for a student with the name "Henry Moore" and the id "557214"?
     
  5. Create a Student with name "djb" and id "859012". What happens when getLoginName is called on this student? Why do you think this is?

 

2.17 Summary

 public class Book
 {
    private String author;
    private String title;

    public Book( String bookAuthor, String bookTitle )
   {
       author = bookAuthor;
       title = bookTitle;
    }

 }

 

Exercise 15 - Summary

In BlueJ:

  1. Open project chapter02\book-exercise
    • Examine in the editor.
       
  2. Exercise 2.65 of text.
    • Add two methods printAuthor and printTitle to the Book class. These should print the author and title fields to the terminal window.
    • Create a Book instance and call each method.
       
  3. Exercise 2.66 of text.
    • Add another field pages, to the Book class to store the number of pages.
    • This should be of type int with an initial value passed, along with the author and title strings to the single Book constructor.
    • Add an accessor method getPages.
    • Create a Book instance and call getPages method.

 

Challenge Exercise 16 - Creating a class

In BlueJ:

  1. Click:
    • Project | New Project
       
  2. Type:
    • heater exercise
       
  3. Click:
    • New Class
       
  4. Type:
    • Heater
       
  5. Open Heater class in editor.
     
    • Add a field temperature of type int .
       
    • Delete the field x.
       
    • Delete sampleMethod.
       
    • Change the Heater constructor to initialize temperature to 15.
       
    • Add accessor method to return the value of temperature.
       
    • Compile.
       
    • Create a Heater instance and call accessor method.
       
  6. Add mutator methods warmer and cooler to increase or decrease the temperature field by 5 each time the appropriate method is called.
    • Compile.
    • Create a Heater instance and call both mutator and accessor methods to test.
       
  7. Add a method to print the current temperature value.