CSCI 201
Introduction to Algorithm Design home | homework index | labs index |
FALL 2006 |
An object is an entity that lives in the heap. It is created from a class while your program is running. Objects contain instance variables, which encode object properties, and instance methods, which act on those properties.
When you write a java program, you write
classes. In general, a class is a
template for making objects: each object can be thought of as
a realization of a class. The class defines both the instance
variables and the methods of the object. The process of
creating a new object from a class is called
instantiation. You use the keyword
new
to
instantiate an object.
For example, the code:
new myClass();
would create an object in the heap from the
class myClass
and then return a reference to
that object. Unfortunately, Java can't refer to
things in the heap by a name. After an object is created, the
system forgets where it is. So, in order to use objects, we
must store their locations in reference
variables.
Simply put, a reference variable stores
an address of an object and thus
serves as the object's name.
Very simple values, like integers and doubles,
are not objects. They are
primitive data types. You can think of
primitive variables as storing data,
and reference variables as storing links to data.
Creating reference
variables is just like creating primitive variables. When you
create a new reference variable, it links to nothing. You can make
it link to an object by assigning it
the value returned by
new
. Pretend we have a class called
intHolder
which looks like this:
class intHolder { private myInt; public intHolder (int newInt) { myInt = newInt; } public int getInt() { return myInt; } }
The following Stack N' Heap demonstrates the difference between primitive and reference variables.
Code
int prim = 5;
intHolder ref = new intHolder(5); System.out.println( "prim = " + prim ); System.out.println( "ref.getInt() = " + ref.getInt() ); |
Stack
|
Heap
|
Temporary
|
Objects can have both state and
behavior. The state of an object is
maintained in instance variables while
instance methods provide the behavior.
Suppose you had two intHolder
objects, one called
bi
which has 2
in its instance variable, and one called
tri
which has 3
in it's instance variable. If you typed the command:
bi.getInt();
you would run the instance method
getInt
in the
bi
object. This would return the
number 2.
Unlike instance variables and methods,
static variables and methods are
not part of any object. They are associated
with the object's class.
When you create a static
variable, only one copy of that variable will ever exist in
memory. The same is true for a static method. When you
call a static method or use a static variable, you give the
name of the class first, followed by a
period, and then the name of the static method or variable. For
example, lets say that the intHolder
class has a static
variable called maxValue
.
The definition for it might look like this
inside the class:
public static int maxValue = 3000;
To access the maxValue
variable from any place in your
program, you would type
intHolder.maxValue
. Because there can
be only one class called intHolder
in
your program, there is also only one variable called
intHolder.maxValue
. Any intHolder
object that you instantiate from this class would
not have its own maxValue
. However, you can
access the intHolder.maxValue
variable from within
instance methods, just as you would from anywhere
else in your program.
Static variables are generally used for constants that
are appropriate for all objects of the class.
Public static variables are also appropriate for widely
used program constants, such as Color.BLUE
and System.in
.
Assigning to a static variable is an extreme measure.
The most famous static method is main
, the
entry point for Java applications.
Static methods are also appropriate for object independent
collections of routines,
such as Math.pow
and Math.sin
.
Because static methods are required to have the same behavior for
all instances of a class, they are not allowed to even reference,
let along modify, a non-static instance variable.
This restriction can make the writing of a static method a real
challenge. It's best to avoid them -- except for main
.
When we first instantiated the intHolder
object using
new
, you may have noticed that we
placed a number in parenthesis following the class name:
intHolder ref = new intHolder ( 5 );
.
This number is passed to the intHolder
object's
constructor. A constructor is the
first method that is run when an object is instantiated. The
intHolder
's constructor is:
public intHolder (int newInt) { myInt = newInt; }
To write a constructor, you write a method that has no return type and whose method name the same as the class name. Most constructors look like the one shown above. They receive a collection of parameters which are copied into instance variables. These copies must be made. Otherwise, the parameter value will be lost when the constructor completes.
The constructor, like the one above, is "called" by using
the Java keyword new
as shown below:
intHolder ref = new intHolder(5) ;
When this statement is executed, the Java system allocates new
space for the intHolder
object and transfers to
the intHolder
constructor which should initialize
the instance variables of the object.
When new
is used to construct an object,
it must use a matching constructor. For example,
new intHolder(3.1416)
is not allowed.
This new intHolder
tries to use a double
to construct the object, but the constructor only accepts an int
.
Similarly, both new intHolder()
and
new intHolder(6, 7)
will fail.
One has too few parameters, and the other has too many.
Frequently, a class is defined with multiple constructors, in which
case new
will succeed if it finds a matching constructor.
For example the following constructor, which gives myInt
a default value of 0, would match new intHolder()
.
public intHolder () { myInt = 0; }
You can even match
new intHolder(3.1416)
by including the
followig constructor.
public intHolder (double newNearInt) { myInt = Math.round(newNearInt); }