Simple Java Classes

This web page describes the versions of the Account and AccountTest classes in Chapter 3. The following project file contains these classes and can be imported into Eclipse. The project separates the three different versions into packages. Packages are used to organize classes within different folders. Each class in this project has a package statement at the top, which indicates which folder should contain the class. The names of the packages in chapter3.zip correspond to the sections of Chapter 3 which contain the different versions.

Section 2 Version

Account.java describes a class that contains one field and two methods. The field, named name, is of type String. This means that each Account object contains a String. The field is private, which means that its value can only be accessed by code within Account.java.

The two methods operate on this field. The setName method assigns the value of its parameter to the field. The getName method returns the value of the field. The syntax this.name in the setName method is needed to access the field instead of setName's parameter. The getName method does not have this issue, so name refers to the field in this case.

The main method in AccountName.java creates and modifies an Account object. It also allows the user to enter the name in the console.

The import statement tells Java that this program uses the Scanner class from the java.util package that is part of the Java distribution. The first statement in the main method creates a Scanner object named input that will input values from standard input. The method call input.nextLine() further down in the program returns a String that is read from standard input.

The second statement in the main method uses the new keyword to create an Account object named myAccount. The field within this object will be initialized to null. The statement myAccount.setName(theName); further down changes the value of the name field to the String that the user entered.

Section 3 Version

Rather than creating objects with null, 0 or false fields, one can program and use a constructor to initialize the fields when the object is created. In this version, Account.java contains the constructor and AccountTest.java uses the constructor.

Account.java contains a constructor with a String parameter, which is used to initialize the name field. The syntax public Account tells Java that a constuctor is coming. this.name is needed to refer to the name field instead of the name parameter.

The first two statements in AccountTest.java main method uses the constructor to create two Account objects. Note how the name is passed to the constructor.

Section 5 Version

In this version, Account.java has two fields, a String field named name and a double filed named balance. The constructor has two parameters for initializing the two fileds. Some input validation is done for the constructor as well as the deposit method, but no errors are raised.

The main method of AccountTest.java creates two Account objects using the two-parameter constructor. The remainder of the code allows the user to input a deposit for each Account object, printing the balance after each deposit.

Equivalent Code in C

account.c is C code that is approximately equivalent to the final version of AccountTest.java and Account.java. A Java object can be thought of as a C structure (more precisely, a pointer to a C structure). The methods in Account.java can be thought of as C function calls with an additional parameter, the Java object/C structure. This web page lists some of the important similarities and differences between C and Java.

UML Class Diagram

UML (United Modeling Language) can be used to create graphical models of object-oriented software. AccountTest.java and Account.java can be modeled by the following class diagram.

A rectangle is used to model each class. Within each rectangle, the variables (name and type) and methods (name, parameters, and return type) are listed. Additional symbols indicate whether each element is public(+), private(-), or static(_). The dotted line with an arrow indicates a dependency relationship from AccountTest to Account because the main method of AccountTest uses elements from Account.

The diagram was created using the Violet UML Editor. This is the original file.

Primitive Types and Reference Types

The type of a variable is either a primitive (boolean, char, byte, short, int, long, float or double; see Appendix D) or a reference to an array or object (everything else). A primitive variable directly stores a value of its type. For example, adding the statements:

int number3 = number2;
number2++;

to the Addition class from Chapter 2 would first store a copy of the value of number2 in number3. The second statement increments number2, but does not change number3.

A reference variable stores the location (address) of an array or object. This is like storing a pointer. For example, adding the statements:

Scanner foo = input;
input.close();
int number4 = foo.nextInt();

to the main method in AccountTest.java would first store in foo a reference to (a pointer to) the same Scanner object as input. The following statement closes the Scanner object. The last statement causes a runtime error because foo refers to the Scanner object that was closed.

As another example, suppose the statements:

Account foobar = account2;
foobar.setName("Foo Bar AKA John Blue");
System.out.println(account2.getName());

are added to the main method of AccountTest.java. The first statement stores in foobar a reference to (a pointer to) the same Account object as account2. The second statement changes the name field of this object. The third statement prints Foo Bar AKA John Blue because foobar and account2 reference (point to) the same object. You only get a new object when you use the new keyword (or some method creates a new object and returns it).

toString methods

Account.java can be improved by adding a toString method that returns a String representation of the object.

public String toString() {
    // String.format is a static method in the String class.
    // It is similar to sprintf in C.
    return String.format("Account object: name = %s, balance = $%.2f",
                         name, balance);
}

Now the following statements can be added to the main method of AccountTest.java:

System.out.println(account1);
System.out.println(account2);

An attempt to print an object will implicitly call its toString method.