algorithm 1

STUDY
PLAY

Terms in this set (...)

Building data structures and algorithms requires that we communicate detailed instructions
to a computer. An excellent way to perform such communication is
using a high-level computer language, such as Java. In this chapter, we provide an
overview of the Java programming language, and we continue this discussion in the
next chapter, focusing on object-oriented design principles. We assume that readers
are somewhat familiar with an existing high-level language, although not necessarily
Java. This book does not provide a complete description of the Java language
(there are numerous language references for that purpose), but it does introduce all
aspects of the language that are used in code fragments later in this book.
In Java, executable statements are placed in functions, known as methods, that
belong to class definitions. The Universe class, in our first example, is extremely
simple; its only method is a static one named main, which is the first method to be
executed when running a Java program. Any set of statements between the braces
"{" and "}" define a program block. Notice that the entire Universe class definition
is delimited by such braces, as is the body of the main method.
The name of a class, method, or variable in Java is called an identifier, which
can be any string of characters as long as it begins with a letter and consists of letters,
numbers, and underscore characters (where "letter" and "number" can be from
any written language defined in the Unicode character set). We list the exceptions
to this general rule for Java identifiers
reserved words
abstract /default /goto /package/ synchronized
assert /do/ if /private/ this
boolean double implements protected throw
break else import public throws
byte enum instanceof return transient
case extends int short true
catch false interface static try
char final long strictfp void
class finally native super volatile
const float new switch while
continue for null
...
Comments
In addition to executable statements and declarations, Java allows a programmer
to embed comments, which are annotations provided for human readers that are
not processed by the Java compiler. Java allows two kinds of comments: inline
comments and block comments. Java uses a "//" to begin an inline comment,
ignoring everything subsequently on that line. For example:
// This is an inline comment.
We will intentionally color all comments in blue in this book, so that they are not
confused with executable code.
While inline comments are limited to one line, Java allows multiline comments
in the form of block comments. Java uses a "/*" to begin a block comment and a
"*/" to close it. For example:
/*
* This is a block comment.
*/
Block comments that begin with "/**" (note the second asterisk) have a special
purpose, allowing a program, called Javadoc, to read these comments and automatically
generate software documentation. We discuss the syntax and interpretation
of Javadoc comments in Section 1.9.4
boolean a boolean value: true or false
char 16-bit Unicode character
byte 8-bit signed two's complement integer
short 16-bit signed two's complement integer
int 32-bit signed two's complement integer
long 64-bit signed two's complement integer
float 32-bit floating-point number (IEEE 754-1985)
double 64-bit floating-point number (IEEE 754-1985)
A variable having one of these types simply stores a value of that type. Integer
constants, like 14 or 195, are of type int, unless followed immediately by an 'L'
or 'l', in which case they are of type long. Floating-point constants, like 3.1416
or 6.022e23, are of type double, unless followed immediately by an 'F' or 'f', in
which case they are of type float. Code Fragment 1.1 demonstrates the declaration,
and initialization in some cases, of various base-type variables.
1 boolean flag = true;
2 boolean verbose, debug; // two variables declared, but not yet initialized
3 char grade = 'A';
4 byte b = 12;
5 short s = 24;
6 int i, j, k = 257; // three variables declared; only k initialized
7 long l = 890L; // note the use of "L" here
8 float pi = 3.1416F; // note the use of "F" here
9 double e = 2.71828, a = 6.022e23; // both variables are initialized
Code Fragment 1.1: Declarations and initializations of several base-type variables
Note that it is possible to declare (and initialize) multiple variables of the same
type in a single statement, as done on lines 2, 6, and 9 of this example. In this code
fragment, variables verbose, debug, i, and j remain uninitialized. Variables declared
locally within a block of code must be initialized before they are first used.

A nice feature of Java is that when base-type variables are declared as instance
variables of a class (see next section), Java ensures initial default values if not explicitly
initialized. In particular, all numeric types are initialized to zero, a boolean
is initialized to false, and a character is initialized to the null character by default.
Classes and Objects
In more complex Java programs, the primary "actors" are objects. Every object is
an instance of a class, which serves as the type of the object and as a blueprint,
defining the data which the object stores and the methods for accessing and modifying
that data. The critical members of a class in Java are the following:
• Instance variables, which are also called fields, represent the data associated
with an object of a class. Instance variables must have a type, which can
either be a base type (such as int, float, or double) or any class type (also
known as a reference type for reasons we soon explain).
• Methods in Java are blocks of code that can be called to perform actions
(similar to functions and procedures in other high-level languages). Methods
can accept parameters as arguments, and their behavior may depend on the
object upon which they are invoked and the values of any parameters that are
passed. A method that returns information to the caller without changing any
instance variables is known as an accessor method, while an update method
is one that may change one or more instance variables when called
For the purpose of illustration, Code Fragment 1.2 provides a complete definition
of a very simple class named Counter, to which we will refer during the
remainder of this section.
1 public class Counter { 2 private int count; // a simple integer instance variable
3 public Counter( ) { } // default constructor (count is 0)
4 public Counter(int initial) { count = initial; } // an alternate constructor
5 public int getCount( ) { return count; } // an accessor method
6 public void increment( ) { count++; } // an update method
7 public void increment(int delta) { count += delta; } // an update method
8 public void reset( ) { count = 0; } // an update method
9 }
Code Fragment 1.2: A Counter class for a simple counter, which can be queried,
class includes one instance variable, named count, which is declared at
line 2. As noted on the previous page, the count will have a default value of zero,
unless we otherwise initialize it.
The class includes two special methods known as constructors (lines 3 and
4), one accessor method (line 5), and three update methods (lines 6-8). Unlike
the original Universe class from page 2, our Counter class does not have a main
method, and so it cannot be run as a complete program. Instead, the purpose of the
Counter class is to create instances that might be used as part of a larger program.
Creating and Using Objects
Before we explore the intricacies of the syntax for our Counter class definition, we
prefer to describe how Counter instances can be created and used. To this end,
Code Fragment 1.3 presents a new class named CounterDemo
1 public class CounterDemo { 2 public static void main(String[ ] args) { 3 Counter c; // declares a variable; no counter yet constructed
4 c = new Counter( ); // constructs a counter; assigns its reference to c
5 c.increment( ); // increases its value by one
6 c.increment(3); // increases its value by three more
7 int temp = c.getCount( ); // will be 4
8 c.reset( ); // value becomes 0
9 Counter d = new Counter(5);// declares and constructs a counter having value 5
10 d.increment( ); // value becomes 6
11 Counter e = d; // assigns e to reference the same object as d
12 temp = e.getCount( ); // will be 6 (as e and d reference the same counter)
13 e.increment(2); // value of e (also known as d) becomes 8
14 } 15 }
Code Fragment 1.3: A demonstration of the use of Counter instances
There is an important distinction in Java between the treatment of base-type
variables and class-type variables. At line 3 of our demonstration, a new variable c
is declared with the syntax:
Counter c;
This establishes the identifier, c, as a variable of type Counter, but it does not create
a Counter instance. Classes are known as reference types in Java, and a variable of
that type (such as c in our example) is known as a reference variable. A reference
variable is capable of storing the location (i.e., memory address) of an object from
the declared class. So we might assign it to reference an existing instance or a
newly constructed instance. A reference variable can also store a special value,
null, that represents the lack of an object
In Java, a new object is created by using the new operator followed by a call to
a constructor for the desired class; a constructor is a method that always shares the
same name as its class. The new operator returns a reference to the newly created
instance; the returned reference is typically assigned to a variable for further use.
In Code Fragment 1.3, a new Counter is constructed at line 4, with its reference
assigned to the variable c. That relies on a form of the constructor, Counter( ), that
takes no arguments between the parentheses. (Such a zero-parameter constructor
is known as a default constructor.) At line 9 we construct another counter using a
one-parameter form that allows us to specify a nonzero initial value for the counter.
Three events occur as part of the creation of a new instance of a class:
• A new object is dynamically allocated in memory, and all instance variables are initialized to standard default values. The default values are null for
reference variables and 0 for all base types except boolean variables (which are false by default).
• The constructor for the new object is called with the parameters specified.The constructor may assign more meaningful values to any of the instance
variables, and perform any additional computations that must be done due to the creation of this object.
• After the constructor returns, the new operator returns a reference (that is, a
memory address) to the newly created object. If the expression is in the form
of an assignment statement, then this address is stored in the object variable,
so the object variable refers to this newly created object.
The Dot Operator
One of the primary uses of an object reference variable is to access the members of
the class for this object, an instance of its class. That is, an object reference variable
is useful for accessing the methods and instance variables associated with an
object. This access is performed with the dot (".") operator. We call a method associated
with an object by using the reference variable name, following that by the dot
operator and then the method name and its parameters. For example, in Code Fragment
1.3, we call c.increment( ) at line 5, c.increment(3) at line 6, c.getCount( )
at line 7, and c.reset( ) at line 8. If the dot operator is used on a reference that is
currently null, the Java runtime environment will throw a NullPointerException.
If there are several methods with this same name defined for a class, then the
Java runtime system uses the one that matches the actual number of parameters
sent as arguments, as well as their respective types. For example, our Counter
class supports two methods named increment: a zero-parameter form and a oneparameter
form. Java determines which version to call when evaluating commands
such as c.increment( ) versus c.increment(3). A method's name combined with the
number and types of its parameters is called a method's signature, for it takes all
of these parts to determine the actual method to perform for a certain method call.
Note, however, that the signature of a method in Java does not include the type that
the method returns, so Java does not allow two methods with the same signature to
return different types
A reference variable v can be viewed as a "pointer" to some object o. It is as if
the variable is a holder for a remote control that can be used to control the newly
created object (the device). That is, the variable has a way of pointing at the object
and asking it to do things or give us access to its data. We illustrate this concept in
Figure 1.2. Using the remote control analogy, a null reference is a remote control
holder that is empty
There can, in fact, be many references to the same object, and each reference to
a specific object can be used to call methods on that object. Such a situation would
correspond to our having many remote controls that all work on the same device.
Any of the remotes can be used to make a change to the device (like changing a
channel on a television). Note that if one remote control is used to change the
device, then the (single) object pointed to by all the remotes changes. Likewise, if
one object reference variable is used to change the state of the object, then its state
changes for all the references to it. This behavior comes from the fact that there are
many references, but they all point to the same object.
Returning to our CounterDemo example, the instance constructed at line 9 as
Counter d = new Counter(5);
is a distinct instance from the one identified as c. However, the command at line 11,
Counter e = d;
does not result in the construction of a new Counter instance. This declares a new
reference variable named e, and assigns that variable a reference to the existing
counter instance currently identified as d. At that point, both variables d and e are
aliases for the same object, and so the call to d.getCount( ) behaves just as would
e.getCount( ). Similarly, the call to update method e.increment(2) is affecting the
same object identified by d.
Defining a Class
Thus far, we have provided definitions for two simple classes: the Universe class
on page 2 and the Counter class on page 5. At its core, a class definition is a block
of code, delimited by braces "{" and "}" , within which is included declarations of
instance variables and methods that are the members of the class. In this section,
we will undertake a deeper examination of class definitions in Java.
Modifiers
Immediately before the definition of a class, instance variable, or method in Java,
keywords known as modifiers can be placed to convey additional stipulations about
that definition.
Access Control Modifiers
The first set of modifiers we discuss are known as access control modifiers, as they
control the level of access (also known as visibility) that the defining class grants
to other classes in the context of a larger Java program. The ability to limit access
among classes supports a key principle of object-orientation known as encapsulation
(see Section 2.1). In general, the different access control modifiers and their
meaning are as follows:
• The public class modifier designates that all classes may access the defined
aspect. For example, line 1 of of Code Fragment 1.2 designates
public class Counter {
and therefore all other classes (such as CounterDemo) are allowed to construct
new instances of the Counter class, as well as to declare variables and
parameters of type Counter. In Java, each public class must be defined in a
separate file named classname.java, where "classname" is the name of the
class (for example, file Counter.java for the Counter class definition).
The designation of public access for a particular method of a class allows
any other class to make a call to that method. For example, line 5 of Code
Fragment 1.2 designates
public int getCount( ) { return count; }
which is why the CounterDemo class may call c.getCount( ).
If an instance variable is declared as public, dot notation can be used to directly
access the variable by code in any other class that possesses a reference
to an instance of this class. For example, were the count variable of Counter
to be declared as public (which it is not), then the CounterDemo would be
allowed to read or modify that variable using a syntax such as c.count.
The protected class modifier designates that access to the defined aspect is
only granted to the following groups of other classes:
◦ Classes that are designated as subclasses of the given class through
inheritance. (We will discuss inheritance as the focus of Section 2.2.)
◦ Classes that belong to the same package as the given class. (We will
discuss packages within Section 1.8.)
The private class modifier designates that access to a defined member of a
class be granted only to code within that class. Neither subclasses nor any
other classes have access to such members.
For example, we defined the count instance variable of the Counter class to
have private access level. We were allowed to read or edit its value from
within methods of that class (such as getCount, increment, and reset), but
other classes such as CounterDemo cannot directly access that field. Of
course, we did provide other public methods to grant outside classes with
behaviors that depended on the current count value.
Finally, we note that if no explicit access control modifier is given, the defined
aspect has what is known as package-private access level. This allows
other classes in the same package (see Section 1.8) to have access, but not
any classes or subclasses from other
...
The static Modifier
The static modifier in Java can be declared for any variable or method of a class
(or for a nested class, as we will introduce in Section 2.6).
When a variable of a class is declared as static, its value is associated with
the class as a whole, rather than with each individual instance of that class. Static
variables are used to store "global" information about a class. (For example, a static
variable could be used to maintain the total number of instances of that class that
have been created.) Static variables exist even if no instance of their class exists.
When a method of a class is declared as static, it too is associated with the
class itself, and not with a particular instance of the class. That means that the
method is not invoked on a particular instance of the class using the traditional dot
notation. Instead, it is typically invoked using the name of the class as a qualifier.
As an example, in the java.lang package, which is part of the standard Java
distribution, there is a Math class that provides many static methods, including one
named sqrt that computes square roots of numbers. To compute a square root, you
do not need to create an instance of the Math class; that method is called using a
syntax such as Math.sqrt(2), with the class name Math as the qualifier before the
dot operator.
Static methods can be useful for providing utility behaviors related to a class
that need not rely on the state of any particular instance of that class.
www.it-
The abstract Modifier
A method of a class may be declared as abstract, in which case its signature is provided
but without an implementation of the method body. Abstract methods are an
advanced feature of object-oriented programming to be combined with inheritance,
and the focus of Section 2.3.3. In short, any subclass of a class with abstract methods
is expected to provide a concrete implementation for each abstract method.
A class with one or more abstract methods must also be formally declared as
abstract, because it is essentially incomplete. (It is also permissible to declare
a class as abstract even if it does not contain any abstract methods.) As a result,
Java will not allow any instances of an abstract class to be constructed, although
reference variables may be declared with an abstract type.
The final Modifier
A variable that is declared with the final modifier can be initialized as part of that
declaration, but can never again be assigned a new value. If it is a base type, then
it is a constant. If a reference variable is final, then it will always refer to the same
object (even if that object changes its internal state). If a member variable of a class
is declared as final, it will typically be declared as static as well, because it would
be unnecessarily wasteful to have every instance store the identical value when that
value can be shared by the entire class.
Designating a method or an entire class as final has a completely different
consequence, only relevant in the context of inheritance. A final method cannot be
overridden by a subclass, and a final class cannot even be subclassed.
Declaring Instance Variables
When defining a class, we can declare any number of instance variables. An important
principle of object-orientation is that each instance of a class maintains its own
individual set of instance variables (that is, in fact, why they are called instance
variables). So in the case of the Counter class, each instance will store its own
(independent) value of count.
The general syntax for declaring one or more instance variables of a class is as
follows (with optional portions bracketed):
[modifiers] type identifier1[=initialValue1], identifier2[=initialValue2];
In the case of the Counter class, we declared
private int count;
where private is the modifier, int is the type, and count is the identifier. Because
we did not declare an initial value, it automatically receives the default of zero as a
base-type integer
...