Chapter 2
Chapter 2
2. Introducing Classes
Class is a basis of OOP languages. It is a logical construct which defines shape and nature of an object.
Entire Java is built upon classes.
2.1
Class Fundamentals
Class can be thought of as a user-defined data type. We can create variables (objects) of that data type.
So, we can say that class is a template for an object and an object is an instance of a class. Most of the
times, the terms object and instance are used interchangeably.
A Simple Class
Here we will consider a simple example for creation of class, creating objects and using members of the
class. One can store the following program in a single file called BoxDemo.java. (Or, two classes can be
saved in two different files with the names Box.java and BoxDemo.java.)
Program 2.1
class Box
{
double w, h, d;
}
class BoxDemo
{
public static void main(String args[])
{
Box b1=new Box();
Prepared By: Dr. Chetana Hegde, Associate Professor, Dept. of MCA, RNSIT, Bangalore.
Ph. No. 9448301894
Box Class
main()
{
Box b1 = new Box( );
}
Box Instance
BoxDemo Class
JVM
2.2
Heap
Declaring Objects
Creating a class means having a user-defined data type. To have a variable of this new data type, we
should create an object. Consider the following declaration:
Box b1;
This statement will not actually create any physical object, but the object name b1 can just refer to the
actual object on the heap after memory allocation as follows
b1 = new Box ();
Prepared By: Dr. Chetana Hegde, Associate Professor, Dept. of MCA, RNSIT, Bangalore.
Ph. No. 9448301894
We can even declare an object and allocate memory using a single statement
Box b1=new Box();
Without the usage of new, the object contains null. Once memory is allocated dynamically, the object b1
contains the address of real object created on the heap. The memory map is as shown in the following
diagram
Statement
Effect
null
Box b1;
b1
b1 = new Box();
b1
w
h
d
2.3
When an object is assigned to another object, no separate memory will be allocated. Instead, the second
object refers to the same location as that of first object. Consider the following declaration
Box b1= new Box();
Box b2= b1;
Now both b1 and b2 refer to same object on the heap. The memory representation for two objects can be
shown as
b1
w
h
d
b2
Prepared By: Dr. Chetana Hegde, Associate Professor, Dept. of MCA, RNSIT, Bangalore.
Ph. No. 9448301894
Thus, any change made for the instance variables of one object affects the other object also. Although b1
and b2 both refer to the same object, they are not linked in any other way. For example, a subsequent
assignment to b1 will simply unhook b1 from the original object without affecting the object or affecting
b2. For example:
Box b1 = new Box();
Box b2 = b1;
// ...
b1 = null;
Here, b1 has been set to null, but b2 still points to the original object.
NOTE that when you assign one object reference variable to another object reference variable, you are
not creating a copy of the object, you are only making a copy of the reference.
2.4
Introducing Methods
A class can consist of instance variables and methods. We have seen declaration and usage of instance
variables in Program 2.1. Now, we will discuss about methods. The general form of a method is
ret_type method_name(para_list)
{
//body of the method
return value;
}
Here, ret_type
specifies the data type of the variable returned by the method. It may be any
primitive type or any other derived type including name of the same class. If the
method does not return any value, the ret_type should be specified as void.
method_name is any valid name given to the method
para_list
is the list of parameters (along with their respective types) taken the method. It may
be even empty also.
body of method is a code segment written to carryout some process for which the method is
meant for.
return
is a keyword used to send value to the calling method. This line will be absent if
the ret_type is void.
}
}
class BoxDemo
{
public static void main(String args[])
{
Box b1=new Box();
Box b2=new Box();
b1.w=2;
b1.h=4;
b1.d=3;
b2.w=5;
b2.h=6;
b2.d=2;
b1.volume();
b2.volume();
}
}
The output would be
The volume is 24.0
The volume is 60.0
In the above program, the Box objects b1 and b2 are invoking the member method volume() of the Box
class to display the volume. To attach an object name and a method name, we use dot (.) operator. Once
the program control enters the method volume(), we need not refer to object name to use the instance
variables w, h and d.
Returning a value
In the previous example, we have seen a method which does not return anything. Now we will modify the
above program so as to return the value of volume to main() method.
Program 2.3
class Box
{
double w, h, d;
double volume()
{
return w*h*d;
}
}
class BoxDemo
{
public static void main(String args[])
{
Box b1=new Box();
Box b2=new Box();
double vol;
Prepared By: Dr. Chetana Hegde, Associate Professor, Dept. of MCA, RNSIT, Bangalore.
Ph. No. 9448301894
b1.w=2;
b1.h=4;
b1.d=3;
b2.w=5;
b2.h=6;
b2.d=2;
vol = b1.volume();
System.out.println("The volume is " + vol);
System.out.println("The volume is " + b2.volume());
}
}
The output would be
The volume is 24.0
The volume is 60.0
As one can observe from above example, we need to use a variable at the left-hand side of the
assignment operator to receive the value returned by a method. On the other hand, we can directly make
a method call within print statement as shown in the last line of above program.
There are two important things to understand about returning values:
The type of data returned by a method must be compatible with the return type specified by the
method. For example, if the return type of some method is boolean, you could not return an
integer.
The variable receiving the value returned by a method (such as vol, in this case) must also be
compatible with the return type specified for the method.
{
public static void main(String args[])
{
Box b1=new Box();
Box b2=new Box();
b1.set(2,4,3);
b2.set(5,6,2);
System.out.println("The volume of b1 is " + b1.volume());
System.out.println("The volume of b2 is " + b2.volume());
}
}
The output would be
The volume of b1 is 24.0
The volume of b2 is 60.0
In the above program, the Box class contains a method set() which take 3 parameters. Note that, the
variables wd, ht and dp are termed as formal parameters or just parameters for a method. The values
passed like 2, 4, 3 etc. are called as actual arguments or just arguments passed to the method.
2.5
Constructors
Constructor is a special type of member method which is invoked automatically when the object gets
created. Constructors are used for object initialization. They have same name as that of the class. Since
they are called automatically, there is no return type for them. Constructors may or may not take
parameters.
Program 2.5
class Box
{
double w, h, d;
double volume()
{
return w*h*d;
}
Box()
{
//ordinary constructor
w=h=d=5;
}
Box(double wd, double ht, double dp)
{
w=wd;
h=ht;
d=dp;
}
//parameterized constructor
}
class BoxDemo
{
Prepared By: Dr. Chetana Hegde, Associate Professor, Dept. of MCA, RNSIT, Bangalore.
Ph. No. 9448301894
2.6
Every class is provided with a default constructor which initializes all the data members to
respective default values. (Default for numeric types is zero, for character and strings it is null and
default value for Boolean type is false.)
In the statement
classname ob= new classname();
the term classname() is actually a constructor call.
If the programmer does not provide any constructor of his own, then the above statement will call
default constructor.
If the programmer defines any constructor, then default constructor of Java can not be used.
So, if the programmer defines any parameterized constructor and later would like to create an
object without explicit initialization, he has to provide the default constructor by his own.
For example, in Program 2.5, if we remove ordinary constructor, the statements like
Box b1=new Box();
will generate error. To avoid the error, we should write a default constructor like
Box(){ }
Now, all the data members will be set to their respective default values.
Sometimes a method will need to refer to the object that invoked it. To allow this, Java defines the this
keyword. this can be used inside any method to refer to the current object. That is, this is always a
reference to the object which invokes the method call. For example, in the Program 2.5, the method
volume() can be written as
double volume()
{
return this.w * this.h * this.d;
}
Here, usage of this is not mandatory as it is implicit. But, in some of the situations, it is useful as
explained in the next section.
As we know, in Java, we can not have two local variables with the same name inside the same or
enclosing scopes. (Refer Program 1.7 and a NOTE after that program from Chapter 1, Page 16 & 17).
But we can have local variables, including formal parameters to methods, which overlap with the names
of the class instance variables. However, when a local variable has the same name as an instance
variable, the local variable hides the instance variable. That is, if we write following code snippet for a
constructor in Program 2.5, we will not get an expected output
Box(double w, double h, double d)
{
w=w;
h=h;
d=d;
}
Here note that, formal parameter names and data member names match exactly. To avoid the problem,
we can use
Box(double w, double h, double d)
{
this.w=w;
//this.w refers to data member name and w refers to formal parameter
this.h=h;
this.d=d;
}
2.7
Garbage Collection
In C and C++, dynamically allocated variables/objects must be manually released using delete operator.
But, in Java, this task is done automatically and is called as garbage collection. When no references to
an object exist, that object is assumed to be no longer needed, and the memory occupied by the object
can be reclaimed. Garbage collection occurs once in a while during the execution of the program. It will
not occur simply because one or more objects exist that are no longer used. Furthermore, different Java
run-time implementations will take varying approaches to garbage collection.
2.8
Sometimes an object will need to perform some action when it is destroyed. For example, if an object is
holding some non-Java resource such as a file handle or character font, then you might want to make
sure these resources are freed before an object is destroyed. To handle such situations, Java provides a
mechanism called finalization. By using finalization, you can define specific actions that will occur when
an object is just about to be reclaimed by the garbage collector. To add a finalizer to a class, you simply
define the finalize() method. The Java run time calls that method whenever it is about to recycle an
object of that class.
The finalize( ) method has this general form:
protected void finalize( )
{
// finalization code here
}
Here, the keyword protected is a specifier that prevents access to finalize( ) by code defined outside its
class. Note that finalize( ) is only called just prior to garbage collection. It is not called when an object
goes out-of-scope. So, we can not know when finalize() method is called, or we may be sure whether it
is called or not before our program termination. Therefore, if at all our program uses some resources, we
should provide some other means for releasing them and must not depend on finalize() method.
2.9
A Stack Class
To summarize the concepts of encapsulation, class, constructor, member initialization etc, we will now
consider a program to implement stack operations.
Prepared By: Dr. Chetana Hegde, Associate Professor, Dept. of MCA, RNSIT, Bangalore.
Ph. No. 9448301894
10
Program 2.6
class Stack
{
int st[] = new int[5];
int top;
Stack()
{
top = -1;
}