slanted W3C logo

Day 10 — Object Creation 1

In today's lecture we look at what happens when you create an object.

Fractions

Java's built-in primitive types lets the client represent integer and real numbers, but there is no primitive type that represents fractions. The ability to represent fractions might be useful when you need to write software for North American manufacturers, home builders, home owners, etc., where the US customary system of measurement (feet, inches, fractions of inches) is commonly used.

You could as the client keep track of all of the fraction numerators and denominators, but this quickly becomes cumbersome:

import java.io.PrintStream;

public class YuckFractions
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       
       // computes Example 4.3 from the textbook manually
       int num1 = 5;
       int den1 = 3;
       
       int num2 = 7;
       int den2 = 6;
       
       int num3 = 31;
       int den3 = 45;
       
       int num4 = 3;
       int den4 = 4;
       
       // compute (num1 / den1) x (num2 / den2)
       int num5 = num1 * num2;
       int den5 = den1 * den2;
       
       // compute (num5 / den5) / (num3 / den3)
       int num6 = num5 * den3;
       int den6 = den5 * num3;
       
       // compute (num6 / den6) + (num4 / den4)
       int num7 = num6 * den4 + num4 * den6;
       int den7 = den6 * den4;
       
       output.printf("%d/%d%n", num7, den7);
   }
}

type.lib.Fraction

The type.lib package provides a Fraction class that encapsulates the idea of a fraction. It provides methods for fraction arithmetic, getting and setting the values of the numerator and denominator, and many other actions.

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

public class YippeeFractions
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       
       Fraction f = new Fraction(5, 3);
       
       f.multiply(new Fraction(7, 6));
       f.divide(new Fraction(31, 45));
       f.add(new Fraction(3, 4));
       output.println(f);
   }
}

Recap: What Does int x; Mean?

Recall that the statement int x; reserves a block of memory large enough to hold an int and labels the block with the identifier x.

0
 
  ¦
  main
 
x ⇒ 100
 
 
 
104
  ¦

Recap: What Does x = 17; Mean?

Recall that the statement x = 17; stores the value of 17 in the memory reserved for the variable x.

0
 
  ¦
  main
 
x ⇒ 100 17
 
 
 
104
  ¦

What Does Fraction f; Mean?

The statement Fraction f; is similar to the the statement int x;. It causes a block of memory to be reserved that is large enough to hold what is called a reference to a Fraction object and labels the block with the identifier f.

0
 
  ¦
  main
 
f ⇒ 100
 
 
 
104
  ¦

Unlike the primitive types, the Java Language Specification does not say how much memory a reference occupies; here we have shown a 4 byte reference, but the size could be different depending on what virtual machine is being used.

We say that f is a reference variable that holds a value that refers to a Fraction object (or a Fraction instance). In this example, the actual Fraction object has not yet been created, so no value is set for the memory block starting at 100.

Loading the Fraction Class

Recall that a class serves as a blueprint for creating objects; the Fraction class serves as a blueprint for creating Fraction objects.

The first time that the running program uses the Fraction class, the compiled class is loaded somewhere into memory. In our memory diagram model, the class is shown as a block of memory that contains the attributes, methods, and constructors of the class. Not all of the features need to shown in the memory diagram; in the example below we only show the attributes that represent the numerator and denominator:

0
 
  ¦
  main
 
f ⇒ 100
 
  ¦
  ¦
500 Fraction class
numerator ⇒ 504
denominator ⇒ 520
 
  ¦

What Does new Fraction(5, 3) Mean

The expression new Fraction(5, 3) creates a new Fraction object with a numerator of 5 and a denominator of 3. In our memory diagram model, you can think of the expression as leading to the following sequence of events:

  1. allocate a block of memory large enough to hold a Fraction object
  2. copy the Fraction class into the allocated block of memory
  3. set the value of the numerator attribute to 5 and the denominator attribute to 3.
0
 
  ¦
  main
 
f ⇒ 100
 
  ¦
500 Fraction class
numerator ⇒ 504
denominator ⇒ 520
 
  ¦
600 Fraction object
numerator ⇒ 604 5
denominator ⇒ 620 3
 
  ¦

Notice that the class Fraction is not used to store the values of the numerator or denominator; the class (in this case) is only used as a template to create the Fraction object. The object is responsible for storing the values of the numerator and denominator.

What Does f = new Fraction(5, 3) Mean

The statement f = new Fraction(5, 3) causes a value to be stored in the memory reserved for the variable f. But what value is stored there?

Recall that f is a reference variable; thus it must hold some value that refers to an object in memory. We shall use for the value the memory address of the block of memory holding the newly created Fraction object.

0
 
  ¦
  main
 
f ⇒ 100 600
 
  ¦
500 Fraction class
numerator ⇒ 504
denominator ⇒ 520
 
  ¦
600 Fraction object
numerator ⇒ 604 5
denominator ⇒ 620 3
 
  ¦

Notice that the Fraction object looks like a copy of the Fraction class; the object also has:

What is a Reference?

reference
a value that refers to an object

Whenever you declare a variable whose type is some sort of object (i.e. not a primitive like int or double) you are declaring a reference variable.

A reference variable holds a reference. A reference is some value that ultimately refers to an object in memory. In the preceding examples, we assumed that the reference was the memory address of an object.

The statement:

Fraction f = new Fraction(5, 3);

means f is a variable whose value refers to a Fraction object.

f IS NOT a Fraction object.
f IS NOT a Fraction object.
f IS NOT a Fraction object.

one more time...

f IS NOT a Fraction object.

Multiple References to an Object

You can have multiple reference variables that all refer to the same object.

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

public class YippeeFractions2
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       
       Fraction f = new Fraction(5, 3);
       Fraction g = f;
       
       f.multiply(new Fraction(7, 6));
       f.divide(new Fraction(31, 45));
       f.add(new Fraction(3, 4));
       output.println(f);
       output.println(g);

       Fraction h = g;
       output.println(h);
   }
}

In the above example, f, g, and h all refer to the same Fraction object which results in the fraction 443/124 being printed 3 times.

What Does Fraction g = f; Mean

The statement Fraction g = f; does not create a new Fraction object. Instead, a block of memory is reserved to hold a reference to a Fraction object and the block is labelled with the name g. Then the value of f is copied into the memory block named g.

0
 
  ¦
  main
 
f ⇒ 100 600
g ⇒ 104 600
 
  ¦
500 Fraction class
numerator ⇒ 504
denominator ⇒ 520
 
  ¦
600 Fraction object
numerator ⇒ 604 5
denominator ⇒ 620 3
 
  ¦

Self Check

  1. Key concepts at the end of Chapter 3.
  2. Review questions at the end of Chapter 3.
  3. Problems at end of the slides.

To Do For Next Lecture

  1. Finish reading Chapter 4 of the textbook.