slanted W3C logo

Day 12 — Recap and Miscellaneous

In today's lecture we review the concepts of reference equality, object equality, accessors, and mutators. We also look at the consequences of badly designed class, and exactly what static means for attributes of a class.

Recap: Reference Equality and Object Equality

Suppose you have two references to unique objects:

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

The statement:

boolean sameObject = (f == g);

is true if and only if the references f and g refer to the same object.

The statement:

boolean differentButSimilarObject = f.equals(g);

is true if and only if the state of the objects referred to by f and g are the same (as defined by the implementer of the class).

Quiz 1

What does the following code fragment output?

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

output.println(f.getNumerator());
output.println(f == g);
output.println(f.equals(g));

Quiz 2

What line of code would you need to add to:

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

// your line of code here

output.println(f.getNumerator());
output.println(f == g);
output.println(f.equals(g));

to produce the following output?

3
true
true

Quiz 3

What line of code would you need to add to:

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

// your line of code here

output.println(f.getNumerator());
output.println(f == g);
output.println(f.equals(g));

to produce the following output?

3
false
true

Quiz 4

What line of code would you need to add to:

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

// your line of code here

output.println(f.getNumerator());
output.println(f == g);
output.println(f.equals(g));

to produce the following output?

1
false
true

Quiz 5

What line of code would you need to add to:

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

// your line of code here

output.println(f.getNumerator());
output.println(f == g);
output.println(f.equals(g));

to produce the following output?

6
false
false

Quiz 6

What line of code would you need to add to:

Fraction f = new Fraction(1, 2);
Fraction g = new Fraction(3, 4);

// your line of code here

output.println(f.getNumerator());
output.println(f == g);
output.println(f.equals(g));

to produce the following output?

1
true
false

Recap: Accessors and Mutators

An accessor is a method that lets the client read the value of an attribute. More generally, an accessor performs some action using the attributes of the object but does not modify the values of the attributes.

A mutator is a method that lets the client write the value of an attribute. More generally, a mutator performs some action that modifies the attributes of the object.

By providing accessor and mutator methods, the class implementer can hide all of the attributes from the client (make them private). From the client's point of view, this is a good thing because the client can use the class without knowing the details of how it is implemented.

The Consequences of public Attributes

The Fraction class has a public attribute named separator that stores the value of the character used to separate the numerator and denominator in the toString method.

import type.lib.Fraction;

public class SeparatorExample1
{
   public static void main(String[] args)
   {
      Fraction f = new Fraction();
      System.out.println(f.separator);
      System.out.println(f);

      f.separator = ':';
      System.out.println(f.separator);
      System.out.println(f);
   }
}

The Consequences of public Attributes

Because the attribute is public, the client can change the attribute value to something inappropriate (i.e. the client can put the object into an invalid state).

import type.lib.Fraction;

public class SeparatorExample2
{
   public static void main(String[] args)
   {
      Fraction f = new Fraction();
      f.separator = '0';
      System.out.println(f.separator);
      System.out.println(f);
   }
}

The Consequences of public Attributes

The Fraction class was intentionally implemented with a public attribute to illustrate the fact that public attributes allow a client to easily put an object into an invalid state.

If the client had used the setSeparator mutator, the Fraction object could have prevented itself from being put into an invalid state.

import type.lib.Fraction;

public class SeparatorExample3
{
   public static void main(String[] args)
   {
      Fraction f = new Fraction();
      boolean separatorOK = f.setSeparator('0');

      System.out.println(separatorOK);
      System.out.println(f.separator);
      System.out.println(f);
   }
}

The advantage of forcing the client to use a mutator method is that the method can do something if the client tries to put the object into an invalid state:

static Attributes

If a class has a static attribute, then the class is responsible for storing the attribute (i.e. each object of the class does not have its own version of the attribute).

The Fraction class has a public static attribute that controls how each Fraction object computes the textual representation of itself as a proper fraction.

import java.io.PrintStream;
import type.lib.Fraction;

public class StaticExample1
{
   public static void main(String[] args)
   {
      PrintStream output = System.out;
      
      Fraction f = new Fraction(25, 8);

      output.println(Fraction.isQuoted);
      output.println(f.toProperString());
      output.println();

      Fraction.isQuoted = false;
      output.println(Fraction.isQuoted);
      output.println(f.toProperString());
   }
}

static Attributes Memory Diagram

Below is the memory diagram for the previous example up to the point just after the Fraction object is printed the first time. Notice that the class stores the static attribute isQuoted whereas the object stores the values for the numerator and denominator.

0
 
  ¦
  main
 
f ⇒ 100 600
 
  ¦
500 Fraction class
numerator ⇒ 504
denominator ⇒ 520
isQuoted ⇒ 524 true
 
  ¦
600 Fraction object
numerator ⇒ 604 25
denominator ⇒ 620 8
 
  ¦

When the client sets the value of isQuoted to false the value stored at address 524 is changed to false.

See the discussion in Section 4.3.3 of the textbook.

Self Check

  1. Try to work through Lab 4 in the textbook (page 162—168).

To Do For Next Lecture

  1. Read Section 5.1 of the textbook.