Chapter 3: Using Classes and Objects

Version 3.31

Handouts: none

(First Day)

In Chapter 2, we began by studying basic features of the Java language and ended by studying some of the Java libraries, such as applet and graphics libraries, which are not part of the language as such.

In Chapter 3, we are still looking at libraries, but mostly libraries which are considered part of the Java language itself because they belong to the package java.lang which is always accessible (without an import statement).

In particular, the String and Math classes are in this core java.lang package. Enumerated types and wrapper classes (sec. 3.7– 3.8) are also language features. The chapter ends, again, by looking at more peripheral classes in the graphics packages.

There are a lot of library classes in Java. Exams will emphasize the core language features and classes (java.lang), and a little of java.util. Don't try to memorize details of things that are outside of the core.

Installing DrJava

(3.1) Creating Objects

The new operator creates an object, initializes it by calling its constructor, and returns a reference to the object.

References are pointers and we may represent them as arrows.

Dot operator (.) accesses methods of an object.

The length method.

What happens if the variable is null?

Aliases: more than one variable referencing the same object. Assigning the value of one reference variable to another: only the pointer is copied, not the object it points at. This creates an alias. If we now mutate the object pointed at by one of the variables, we are also mutating the object pointed at by the other, since they are the same object. (The example on p. 117 is bad because Strings are not mutable.)

Solutions:

Garbage collection

(3.2) String methods

Some important methods of the String class: see Figure 3.1 p. 119.

Some important methods (p. 119)

Examples—evaluate:

String s = "Mississippi";
s.charAt(0)
s.charAt(2)
s.compareTo("Alabama")
"cat".concat("dog")
"cat".equals("dog")
"cat".equalsIgnoreCase("Cat")
s.length()
s.replace('s', 't')
s.replace('s', 't').replace('p', 'q').replace('i', 'j').replace('M', 'N')
s // unchanged
s.substring(0, 4)
s.substring(4, 8)
s.toLowerCase()
s.toUpperCase()

Discussion: compare with string operations in Python.

Listing 3.1 StringMutation (but it does not really mutate the string!)

(3.3) Packages

A class library consists of a group of related classes.

There is also an unnamed package. When you're writing your program, and you don't make a package declaration, by default you're writing for the unnamed package.

The import statement allows us to omit the package name subsequently when we refer to a class, or to any of the classes, in a package. Because java.lang is so fundamental, it does not need to be imported.

An Application Programming Interface (API) also is a collection of related classes, which may belong to one or more packages. E.g., the Java graphics API includes at least the packages java.awt and javax.swing.

When using a library or an API, we usually need to have a reference manual or at least some notes handy. There is just too much to keep in the brain!

→→Visit the Sun Java API documentation web site and navigate.

(3.4) Random and its methods

Random = java.util.Random. Fig. 3.4 lists some of its methods.

Examples:

import java.util.Random;
Random r = new Random();
r.nextFloat()
r.nextInt()
r.nextInt(100)  // overloaded

Listing 3.2: RandomNumber

(3.5) Math and its methods

Math = java.lang.Math

The Math class provides essentially mathematical functions, defined as static methods (class methods). "Static" means we don't need an instance. To use the static methods, we just write class name, dot, method name, e.g., Math.sqrt(16.2).

Fig. 3.5 lists some important Math methods.

Examples:

Math.abs(-7)
Math.floor(7.9)
Math.floor(-7.9)
Math.ceil(7.1)
Math.ceil(-7.1)
Math.pow(2, 8)
Math.exp(8)  // e to the 8th power
Math.sqrt(2.0)
Math.cos(0);

Listing 3.3: Quadratic

Review: to solve quadratic equations, ax2 + bx + c = 0, we use the quadratic formula:

x = [−b ± sqrt(b2 − 4 ac)] / (2 a)

which has two solutions.

(3.6) Formatting Output

The class java.text.NumberFormat

Examples:

import java.text.NumberFormat;
NumberFormat nf;
nf = NumberFormat.getCurrencyInstance();
nf.format(12345.6789)
nf = NumberFormat.getPercentInstance();
nf.format(12345.6789)
nf = NumberFormat.getNumberInstance();
  // or getInstance()
nf.format(12345.6789)

Why using static methods? It's an abstract class, so new isn't going to work. The getInstance method will try to return an object that is appropriate for our locale, i.e., language and other local characteristics. To run gedit in French, for example, try

$ env LANG=fr_FR gedit

Also:

$ export LANG=fr_FR
$ gedit

The first way sets the shell variable LANG for the duration of a single command. The second way sets it for all subsequent commands (unless you change it again later).

Similarly fr_CA for Canadian French, es_ES for Spanish, en_UK for British English. (Some programs respond better to this than others.)

To see all available locale codes:

$ locale -a

Fig 3.6 lists some of its methods but omits:

static NumberFormat getInstance()
static NumberFormat getNumberInstance()

both of which return a general-purpose format object (i.e., not for percentages or currency, just plain numbers; see Java API documentation for java.lang.NumberFormat). (These two methods, getInstance and getNumberInstance, are equivalent.)

Listing 3.4 Purchase

The class java.text.DecimalFormat

Example:

import java.text.DecimalFormat;
DecimalFormat df = new DecimalFormat("0.###");
df.format(123.4)
df.format(123.456789)

Listing 3.5 CircleStats

The printf method (System.out.printf)

Example:

System.out.printf("%s says %d + %3.1f = %4.8f\n",
                  "John", 1, 2.51111, 3.51111);

Discussion (if time)


(Second Day)

(3.7) Enumerated Types

Methods include:

Examples:

> enum Size {Small, Medium, Large};
> Small.name()
Static Error: Undefined name 'Small'
> Size.Small.name()
"Small"
> Size.Small.ordinal()
0
> Size.Small.toString()
"Small"

The Enum class documentation says toString is normally preferred to name, and "most programmers will have no use for" the ordinal method.

(3.8) Wrapper Classes

Recall that Java types are divided into primitive and reference types, and the primitive types include boolean and various kinds of numbers. This is efficient, but sometimes annoying, because some contexts require an object (a reference type of value) and cannot use a primitive type value; for example, an array (a "list") of objects cannot store an int (directly).

Wrapper classes bridge the gap: each one stores a primitive type value and encloses it in an object. Like putting a letter into an envelope—there is some machinery (at the Post Office?) that handles only envelopes.

There is one wrapper class for each primitive type (Fig. 3.8). Mostly, wrapper classes have the same names as the primitive types, except they are capitalized (e.g., Boolean is the wrapper class for the primitive type boolean). Two exceptions:

It is not clear what the Void class is for. The Java API documentation states that "The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void." Since the keyword void does not signify a primitive type, but rather the absence of a return value, why would anyone want or need a Void class?

Example:

Integer w = new Integer(67);
int i = w.intValue(); // 67

Wrapper Utilities

In addition, the wrapper classes provide a number of useful methods ("utilities"). Some of these convert between strings and other types, for example, for the int type:

> Integer.parseInt("35")
35
> Integer.toString(35)
"35"

Students in Information Representation (I308) may be interested in converting to and from bases other than 10:

> Integer.parseInt("111", 2)
7
> Integer.parseInt("777", 8)
511
> Integer.parseInt("ffff", 16)
65535
> Integer.toBinaryString(-35)
"11111111111111111111111111011101"
> Integer.toOctalString(-35)
"37777777735"
> Integer.toHexString(-35)
"ffffffdd"
> Integer.toString(35, 2)
"100011"
> Integer.toString(35, 8)
"43"
> Integer.toString(35, 16)
"23"
> Integer.toString(35, 12)
"2b"

(Note in 7th edition page 142: tohexString should be toHexString)

Autoboxing and Unboxing

Java 1.5 ("Java 5") introduced autoboxing and (auto-) unboxing, making the compiler do the boring part, so we can write just

Integer w = 67;
int i = w;

and it does the same thing.

Another role of the wrapper classes is to provide conversion between the primitive types and their String representations. Examples:

w.toString(); // "26"
int i = Integer.parseInt("26"); // 26
Integer.toString(37) // "37"

(3.9) Graphics: Components and Containers

While the Turtle graphics system that we used in Python last semester has little use, outside of educating beginner programmers, the Java graphics that we are about to learn are "real world" graphics; it and other similar APIs are widely used by experienced programmers for developing "real world" applications.

Components [also called widgets, outside of Java] are elements of a GUI such as buttons and labels.

Containers are components that may contain other components.

Two container classes: JFrame, JPanel.

JFrame is a "heavyweight" component with multiple panes. Its content pane contains all of its visible components.

Another component class: JLabel. Represents a label which can contain text and/or an image.

A container's layout manager controls the arrangement of its components, and may rearrange them when the window is resized.

An important advantage of layout managers is that the programmer does not have to specify numerical coordinates for most components. Specifying such coordinates would make the program very inflexible: the coordinates assume a fixed-size window.

Listing 3.7 Authority

(3.10) Nested Panels

We may use panels within a panel for better control of grouping.

Listing 3.8 NestedPanels

(3.11) Images

Images can be drawn by the Graphics method drawImage. They can also be used, with or without text, in a JLabel.

Usage (javax.swing.ImageIcon):

ImageIcon icon = new ImageIcon("IMAGEFILE"); // gif, jpeg, png

new JLabel(TEXT, ICON, POSITION)

where

All the arguments are optional, but a POSITION argument can be given only if there is at least one of the other arguments. See API documentation, which shows 6 variants of the construction.

To control the position of text vis-a-vis image in the label, use

label.setHorizontalTextPosition(POSITION);

where POSITION allows the same values as above.

Listing 3.9 LabelDemo

Discussion

Programming Projects for discussion in class (time permitting)—Use incremental development, starting with comments:

Lab assignment: …


  1. Version log:
    • Version 3.3, 2012 Jan 21. Minor edit.
    • Version 3.2, 2011 Jan 28. Converted to markdown.
    • Version 3.1, 2010 Jan 27. Corrected formatting of printf and changed the discussion and lab problems.
    • Version 3, 2010 Jan 23. Converted to RST.
    • Version 2, 2009 Jan 28. Updated for 6th edition.