next up previous
Next: Printing Object Values Up: Java Mechanics Previous: Java Statements


The Structure of Java Programs

Every Java program consists of a collection of classes--nothing else. A class is a template for creating a particular form of object. A Java class definition corresponds to a Scheme struct definition generalized to include all of procedures that process objects of the defined class. In Java, all program code is attached to some class.

Each object created by a class template contains the same members, each of which is either a field or a method. A field is a ``container'' that holds a value. A method is an operation on the fields of the object and any values that are passed as arguments to the method. The objects created by a particular class template are called the instances or objects of that class. Each instance contains the members specified in the class template.

Each member of a class has a name consisting of a Java identifier (defined above in Section 1.3.4). For now, we will require all such names to be unique within a class. We will slightly relax this restriction when we discuss overloading in Section 1.12.4.

Java objects are a generalization of Scheme structs. In Java, the collection of operations (methods) that operate an object is determined by the class definition for the object. In Scheme, the set of operations for manipulating a struct is fixed: a constructor, a recognizer, field-accessors, and field-modifiers.

The Java program in Figure 1 defines a class Entry suitable for representing entries in the department directory application described in Section 1.2:

class Entry {

  /* fields */ 
  String name;	
  String address;
  String phone;

  /* constructor */
  Entry(String n, String a, String p) {
    this.name = n;
    this.address = a;
    this.phone = p;
  }	 	 

  /* accessors */
  String getName() { return this.name; }
  String getAddress() { return this.address; }
  String getPhone() { return this.phone; }

}
Figure 1: The Entry class
This class is the Java analog of the Scheme structure definition
(define-struct Entry (name address phone))
where the name, address and phone fields are always bound to strings.

Let's examine the syntax of the Entry class definition in detail. It consists of seven members:

An instance (object) of the class Entry is created by an expression of the form

new Entry("SomeName","SomeAddress","SomePhone")
The expression is equivalent to the Scheme expression
(make-Entry "SomeName" "SomeAddress" "SomePhone")
which creates a Scheme Entry object. The three accessor methods getName, getAddress, and getPhone are equivalent to the Scheme accessors Entry-name, Entry-address and Entry-phone that are automatically generated by the Scheme define-struct definition.

Recall the syntax for method invocation in Java is quite different from the syntax for functional application in Scheme. Given an instance e of class Entry, the expression

e.getName()
invokes the getName method of object e. The equivalent Scheme expression is written
(Entry-name e)

The three methods defined in class Entry are extremely simple, yet they illustrate the most important characteristic of object-oriented programming: operations are attached to the data objects that they process. The methods getName, getAddress, and getPhone take no arguments yet they have access to the fields of the Entry object to which they are attached. The Entry object e in the method call

e.getName()
is called the receiver because it ``receives'' the method call. (In the Java Language Specification, the term target is used instead of receiver.)

In Java, a method cannot return a value without executing a statement of the form

return e;
where e is some expression. Since Java is statement-oriented language, the body of a method is a sequence of statements rather than an expression. When execution reaches a return statement, the specified expression is evaluated and the resulting value is returned as the value of the method call. Hence, the body of each of the three methods in the Entry class is a return statment.

In the code for the Entry class, the constructor and accessor methods all refer to fields of this, the hidden parameter bound to the object that is the receiver of the method invocation. For example, the expression

this.name
returns the value of the name field of the object this. In constructor invocations, this is bound to the newly allocated object.

One attractive feature of Java is that the method syntax mandates a contract (declaration of input types and output type) as part of the method header. For example, the method header

String getName()
indicates that the getName method takes no arguments (other than the ``receiver'' as an implicit argument this and returns a String value. In subsequent examples, we will define methods that take explicit arguments; the type of each such argument must be declared in the method header.


Finger Exercise 1.3.5.1: In the Definitions pane of DrJava, load the Java program Entry.java and compile the program. In the DrJava Interactions pane, try evaluating the following program text:

Entry zung =  new Entry("Zung", "DH 3098", "x 3835");
Entry cork =  new Entry("Cork", "DH 3104", "x 6042");
zung.getName()
cork.getName()
cork.getPhone()
zung == cork
zung != cork
Did you get the results that you expected? If not, ask a teaching assistant to explain any of the results that you do not understand.


We will explain the syntax of Java class definitions in more detail in Section 1.5.


next up previous
Next: Printing Object Values Up: Java Mechanics Previous: Java Statements
Corky Cartwright 2004-02-05