You are on page 1of 405

OBJECT ORIENTED CONCEPTS(18CS45)

Module 1
A Review of structures
Defining a Structure
• To define a structure, you must use the struct statement.
• The struct statement defines a new data type, with more than one
member, for your program.
• The format of the struct statement is this
Syntax: Example:
struct [structure tag] { struct Books {
member definition; char title[50];
member definition; char author[50];
... char subject[100];
member definition; int book_id;
} [one or more structure variables]; } book;
Accessing Structure Members
• To access any member of a structure, we use the member access
operator (.).
• The member access operator is coded as a period between the
structure variable name and the structure member that we wish to
access.
• You would use struct keyword to define variables of structure type.
• Following is the example to explain usage of structure −
#include <iostream> Continued..
#include <cstring> // book 2 specification
strcpy( Book2.title, "Telecom Billing");
using namespace std; strcpy( Book2.author, "Yakit Singha");
strcpy( Book2.subject, "Telecom");
struct Books { Book2.book_id = 6495700;
char title[50];
char author[50]; // Print Book1 info
char subject[100]; cout << "Book 1 title : " << Book1.title <<endl;
int book_id; cout << "Book 1 author : " << Book1.author <<endl;
}; cout << "Book 1 subject : " << Book1.subject <<endl;
cout << "Book 1 id : " << Book1.book_id <<endl;
int main() {
struct Books Book1; // Declare Book1 of type Book // Print Book2 info
struct Books Book2; // Declare Book2 of type Book cout << "Book 2 title : " << Book2.title <<endl;
cout << "Book 2 author : " << Book2.author <<endl;
// book 1 specification cout << "Book 2 subject : " << Book2.subject <<endl;
strcpy( Book1.title, "Learn C++ Programming"); cout << "Book 2 id : " << Book2.book_id <<endl;
strcpy( Book1.author, "Chand Miyan");
strcpy( Book1.subject, "C++ Programming"); return 0;
Book1.book_id = 6495407; }
When the above code is compiled and executed, it
produces the following result −
Book 1 title : Learn C++ Programming
Book 1 author : Chand Miyan
Book 1 subject : C++ Programming
Book 1 id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Yakit Singha
Book 2 subject : Telecom
Book 2 id : 6495700
Procedure–Oriented Programming system
• Procedural Programming can be defined as a programming model
which is derived from structured programming, based upon the
concept of calling procedure.
• Procedures, also known as routines, subroutines or functions, simply
consist of a series of computational steps to be carried out.
• During a program’s execution, any given procedure might be called at
any point, including by other procedures or itself.
• Languages used in Procedural Programming:
• FORTRAN, ALGOL, COBOL,
• BASIC, Pascal and C.
Object oriented programming:
• Object Oriented Programming can be defined as a programming model
which is based upon the concept of objects.
• Objects contain data in the form of attributes and code in the form of
methods.
• In object oriented programming, computer programs are designed using
the concept of objects that interact with real world.
• Object oriented programming languages are various but the most popular
ones are class-based, meaning that objects are instances of classes, which
also determine their types.
• Languages used in Object Oriented Programming:
• Java, C++, C#, Python,
• PHP, JavaScript, Ruby, Perl,
• Objective-C, Dart, Swift, Scala.
Comparison of Object Oriented Language with
Procedure Oriented
PROCEDURAL ORIENTED PROGRAMMING OBJECT ORIENTED PROGRAMMING
In procedural programming, program is In object oriented programming, program is
divided into small parts called functions. divided into small parts called objects.
Procedural programming follows top down Object oriented programming
approach. follows bottom up approach.
There is no access specifier in procedural Object oriented programming have access
programming. specifiers like private, public, protected etc.
Adding new data and function is not easy. Adding new data and function is easy.
Procedural programming does not have any
Object oriented programming provides data
proper way for hiding data so it is less
hiding so it is more secure.
secure.
In procedural programming, overloading is Overloading is possible in object oriented
not possible. programming.
In procedural programming, function is In object oriented programming, data is
more important than data. more important than function.
Procedural programming is based on unreal Object oriented programming is based
world. on real world.
Examples: C, FORTRAN, Pascal, Basic etc. Examples: C++, Java, Python, C# etc.
Console I/O
• C++ I/O occurs in streams, which are sequences of bytes. If bytes flow
from a device like a keyboard, a disk drive, or a network connection
etc. to main memory, this is called input operation
• and if bytes flow from main memory to a device like a display screen,
a printer, a disk drive, or a network connection, etc., this is
called output operation.
The Standard Output Stream (cout)
• The predefined object cout is an instance of ostream class. The cout
object is said to be "connected to" the standard output device, which
usually is the display screen.
• The cout is used in conjunction with the stream insertion operator,
which is written as << which are two less than signs as shown in the
following example.
Example:
#include <iostream> When the above code is compiled and executed,
it produces the following result −
using namespace std;
Value of str is : Hello C++
int main() {
char str[] = "Hello C++";

cout << "Value of str is : " << str << endl;


}
Contd..
• The C++ compiler also determines the data type of variable to be
output and selects the appropriate stream insertion operator to
display the value.
• The << operator is overloaded to output data items of built-in types
integer, float, double, strings and pointer values.
• The insertion operator << may be used more than once in a single
statement as shown above and endl is used to add a new-line at the
end of the line.
The Standard Input Stream (cin)
• The predefined object cin is an instance of istream class. The cin object is said to be
attached to the standard input device, which usually is the keyboard.
• The cin is used in conjunction with the stream extraction operator, which is written
as >> which are two greater than signs as shown in the following example.
Example :
#include <iostream>

using namespace std; #When the above code is compiled and executed, it will
prompt you to enter a name. You enter a value and then hit
int main() { enter to see the following result −
char name[50];
Output:
cout << "Please enter your name: "; Please enter your name: cplusplus
cin >> name; Your name is: cplusplus
cout << "Your name is: " << name << endl;

}
Contd..
• The C++ compiler also determines the data type of the entered value
and selects the appropriate stream extraction operator to extract the
value and store it in the given variables.
• The stream extraction operator >> may be used more than once in a
single statement. To request more than one datum you can use the
following −
• cin >> name >> age;
• This will be equivalent to the following two statements −
• cin >> name;
• cin >> age;
Variables in C++
• A variable is a name given to a memory location. It is the basic unit of
storage in a program.
• The value stored in a variable can be changed during program
execution.
• A variable is only a name given to a memory location, all the operations
done on the variable effects that memory location.
• In C++, all the variables must be declared before use.
• A typical variable declaration is of the form:
// Declaring a single variable
type variable_name;

// Declaring multiple variables:


type variable1_name, variable2_name, variable3_name;
Contd..
• A variable name can consist of alphabets (both upper and lower
case), numbers and the underscore ‘_’ character.
• However, the name must not start with a number.
Examples:

// Declaring float variable


float simpleInterest;

// Declaring integer variable


int time, speed;

// Declaring character variable


char var;
Reference Variable
• When a variable is declared as reference, it Example:
#include<iostream>
becomes an alternative name for an existing using namespace std;
variable. int main()
{
• A variable can be declared as reference by int x = 10;
putting ‘&’ in the declaration.
// ref is a reference to x.
int& ref = x;

// Value of x is now changed to 20


ref = 20;
cout << "x = " << x << endl ;

// Value of x is now changed to 30


x = 30;
cout << "ref = " << ref << endl ;

return 0;
}
Output:

x = 20
ref = 30
Function Prototyping
• The Function prototype serves the following purposes –
1) It tells the return type of the data that the function will return.
2) It tells the number of arguments passed to the function.
3) It tells the data types of the each of the passed arguments.
4) Also it tells the order in which the arguments are passed to the
function.
• Therefore essentially, function prototype specifies the input/output
interlace to the function i.e. what to give to the function and what to
expect from the function.
Contd
Ex:

int add ( int, int );

➢ This prototype indicates that the add() function returns a


value of integer type and takes two parameters both of integer
type.
➢ Function prototype is also a statement, it must be ended with
semi-colon.
➢ Providing names to the formal arguments in function
prototype is optional.
Contd…

Why is Prototyping important?

➢ The return value of a function is handled correctly.

➢ Correct number and type of arguments are passed to a function.


Ex: The prototype tells the compiler that the add() function
returns an integer type value.

Thus, the compiler knows how many bytes have to be


retrieved from the place where the add() function is expected to
write its return value and how these bytes are to be interpreted.
Contd…
➢ In the absence of prototypes, the compiler will have to assume the type of the
returned value.

➢ If the assumption and the actual return value are incompatible, then the
compiler will report an error against the function definition and not the function
call.

Thus, function prototyping guarantees protection from errors arising out of


incorrect function calls.
➢ The function prototype also tells the compiler that the add() function accepts
two parameters.

➢ If the program fails to provide such parameters, compiler detects an error.


➢ Function prototyping produces automatic type conversion whenever
appropriate.
Example

#include<iostream.h>
int add(int,int); //functionprototype int add(int a,int b)
void main() {
{ return (a+b);
int x,y,z; }
cout<<“Enter a number: ”;
cin>>x;
cout<<“Enter another number:”;
cin>>y;
z=add(x,y); //functioncall
cout<<z<<endl;
}
Contd…
if the function definition is in a different file to be compiled separately, then no
compile-time errors will arise. Instead, wrong results will arise during run time.
/*Beginning of def.c*/
/*function definition*/ /*Beginning of driver.c*/
struct abc void main()
{ {
char a; int x;
int b; x=test(); //no compile time error!!
float c; printf(“%d”,x);
}; }
struct abc test() /*End of driver.c*/
{ Output: 1688
struct abc a1;
a1.a=‘x’;
a1.b=10; The compiler will not be able to convert a
a1.c=1.1; struc abc to an integer.
return a1; Thus, function prototyping guarantees protection
} from errors arising out
/*End of def.c*/ of incorrect function calls.
Function Overloading
➢ C++ allows two or more functions to have the same name, but
different signature.

➢ The compiler decides which function is to be called based upon the number,
type, and sequence of parameters that are passed to the function call.
Example

A function call first matches the prototype having the same number and type of
arguments and then calls the appropriate function for execution.
Contd…
➢ The compiler first tries to find an exact match in which the types of actual
arguments are the same, and use that function.

➢ If an exact match is not found, the compiler uses the integral promotions to the
actual arguments, such as:

char to float

float to double to find a match.


➢ If the conversion is possible to have multiple matches, then the compiler will
generate an error message.Ex: long square(long n)

double square(double x)
A function call such as square(10) will cause an error because int can be converted
to either long or double, thereby creating an ambiguous situation as to which
version of square() should be called.
Example

/*Beginning of funcOverload.cpp*/
#include<iostream.h> int add(int a,int b)
int add(int,int); //first prototype {
int add(int,int,int); //second prototype return(a+b);
void main() }
{
int x,y;
x=add(10,20); //matches first prototype
y=add(30,40,50); //matches second prototype int add(int a,int b,int c)
cout<<x<<endl<<y<<endl; {
} return(a+b+c);
}

Output
30
120
Contd…
The two function prototypes at the beginning of the program tell the compiler the
two different ways in which the add() function can be called.
When the compiler encounters the two distinct calls to the add() function, it
already has the prototypes to satisfy them both.Thus, the compilation phase is
completed successfully.
The compiler decides which function is to be called based upon the
number, type, and sequence of parameters that are passed to the
function call.
The first function call, x=add(10,20);
it decides that the function that takes two integers as formal arguments is to be
executed.
Accordingly, the linker then searches for the definition of the add() function
where there are two integers as formal arguments.
Similarly, the second call to the add() function
y=add(30,40,50);
is also handled by the compiler and the linker.
Contd…
Function overloading is also known as function polymorphism because, just like
polymorphism in the real world where an entity exists in more than one form, the
same function name carries different meanings.

Default Values for Formal Arguments of Functions


It is possible to specify default values for some or all of the formal
arguments of a function.
If no value is passed for an argument when the function is called,
the default value specified for it is passed.
If parameters are passed in the normal fashion for such an
argument, the default value is ignored.
Contd…
/*Beginning of defaultArg.cpp*/
#include<iostream.h>
int add(int,int,int c=0); //third argument has default value
void main()
{
int x,y;
x=add(10,20,30); //default valueignored
y=add(40,50); //default value taken for the third parameter
cout<<x<<endl<<y<<endl;
}
int add(int a,int b,int c)
{ Output
return (a+b+c); 60
} 90
Example
#include<iostream.h>
int add(int,int b=0,int c=0); //second and third arguments have default values
void main()
{
int x,y,z;
x=add(10,20,30); //alldefault values ignored
y=add(40,50); //default value taken for the third argument
z=add(60); //default value taken for the second and the third
arguments
cout<<x<<endl<<y<<endl<<z<<endl;
}
int add(int a,int b,int c)
{
return (a+b+c);
}
Inline Functions
Inline functions are used to increase the speed of execution of the executable
files.
C++ inserts calls to the normal functions and the inline functions in different
ways in an executable.
An inline function is a function whose compiled code is ‘in line’ with the rest of the
program. That is, the compiler replaces the function call with the corresponding
function code.
With inline code, the program does not have to jump to another location to execute
the code and then jump back.
Inline functions, thus, run alittle faster than regular functions.
1. prefix the definition of the function with the inline keyword and
2. define the function before all functions that call it, that is, define it in the
header file itself.
Example of code in non-inline function
Example
#include<iostream.h>
inline double cube(double x) { return x*x*x; }
void main()
{
double a,b;
double c=13.0;
a=cube(5.0);
b=cube(4.5+7.5);
cout<<a<<endl;
cout<<b<<endl;
cout<<cube(c++)<<endl;
cout<<c<<endl;
}
Introduction to Classes and Objects
Classes are to C++ what structures are to C. Both provide the library
programmer ameans to create new data types.
Issues faced while programming in C : In C, the library programmer
creates structures.
He/she also provides a set of tested bug-free functions that correctly manipulate
the data members of structure variables.
The Date structure and its accompanying functions may be perfect. However,
there is absolutely no guarantee that the client programs will use only these
functions to manipulate the members of variables of the structure.
struct Date d1;
setDate(&d1); //assign system date to d1.
printf(“%d”,d1.month);
d1.month = 13;
The bug arising out of the last line of the main() function above is easily detected
even by a visual inspection.
Nevertheless, the same will certainly not be the case if the code is around 25,000
lines long.
Contd…
Notice that the absence of a facility to bind the data and the code that can have
the exclusive rights to manipulate the data can lead to difficult-to-detect run- time
bugs.
C does not provide the library programmer with the facilities to encapsulate
data,to hide data,and to abstract data.
The C++ compiler provides a solution to this problem. Structures (the struct
keyword) have been redefined to allow member functions also.
Example
#include<iostream.h>
struct Distance
{
int iFeet;
void main()
float fInches;
{
void setFeet(int x) Distance d1,d2;
{ d1.setFeet(2);
iFeet=x; d1.setInches(2.2);
} d2.setFeet(3);
int getFeet() d2.setInches(3.3);
{ cout<<d1.getFeet()<<“ ”<<d1.getInches()<<endl;
return iFeet; cout<<d2.getFeet()<<“ ”<<d2.getInches()<<endl;
} }
void setInches(float y)
{
fInches=y;
}
float getInches()
{
return fInches;
}
};
Contd..
First, we must notice that functions have also been defined within the scope of
the structure definition.
This means that not only the member data of the structure can be accessed
through the variables of the structures but also the member functions can be
invoked.
The struct keyword has actually been redefined in C++.
Member functions are invoked in much the same way as member data are
accessed, that is, by using the variable-to-member access operator.
it is d1.iFeet that gets the value of 2. On the other hand, it is d2.iFeet that gets
the value of 3 when the fourth line is invoked.
Each structure variable contains a separate copy of the member data within itself.
However, only one copy of the member function exists.
However, in the above example, note that the member data of structure variables
can still be accessed directly.
d1.iFeet=2; //legal!!
Private and Public Members
We have put together the data and functions that work upon the data but we
have not been able to give exclusive rights to these functions to work upon the
data.
Problems in code debugging can still arise as before. Specifying member functions
as public but member data as private obtains the advantage.
#include<iostream.h>
struct Distance
{
private: void main()
int iFeet;
float fInches;
{
public: Distance d1,d2;
void setFeet(int x)
{ d1.setFeet(2);
iFeet=x; //LEGAL: private member
accessed by
d1.setInches(2.2);
//member function d2.setFeet(3);
}
int getFeet() d2.setInches(3.3);
{ d1.iFeet++; //ERROR!!: private member
return iFeet;
} //accessed by non-member
void setInches(float y)
{ function
fInches=y; cout<<d1.getFeet()<<“”<<d1.getInches()<<endl;
}
float getInches() cout<<d2.getFeet()<<“ ”<<d2.getInches()<<endl;
{
return fInches;
}
}
};
Example
First, let us have a close look at the modified definition of the structure Distance.
Two new keywords, private and public have been introduced in the definition
of the structure.
Their presence in the foregoing example tells the compiler that iFeet and fInches
are private data members of variables of the structure Distance and the member
functions are public.
Thus, values of iFeet and fInches of each variable of the structure Distance can be
accessed/ modified only through member functions of the structure and not by
any non-member function in the program (again note that it is the iFeet and
fInches of the invoking object that are accessed/modified by the member
functions).
Any attempt to violate this restriction is prevented by the compiler because that
is how the C++ compiler recognizes the private keyword. Since the member
functions are public, they can be invoked from any part of the program.
The keywords private and public are also known as access modifiers or access
specifiers because they control the access to the members of structures.
C++ introduces a new keyword class as a substitute for the keyword struct. In a
structure, members are publicbydefault .
Example

struct Distance
{ struct Distance
private: {
int iFeet; void setFeet(int x) //public by default
float fInches; {
public: iFeet=x;
void setFeet(int x) }
{ int getFeet() //public by default
iFeet=x; {
} return iFeet;
int getFeet() }
{ void setInches(float y) //public by default
return iFeet; {
} fInches=y;
void setInches(float y) }
{ float getInches()
//public by default
fInches=y; {
} return fInches;
float getInches() }
{ private:
return fInches; int iFeet;
} float fInches;
}; };
Example
On the other hand, class members are private by default.This is the only difference between the class
keyword and the struct keyword.
class Distance
{
int iFeet; //private by default
float fInches; //private by default
public:
void setFeet(int x)
{
iFeet=x;
}
int getFeet()
{
return iFeet;
}
void setInches(float y)
{
fInches=y;
}
float getInches()
{
return fInches;
}
};
Objects
Variables of classes are known as objects.
An object of a class occupies the same amount of memory as a variable of a
structure that has the same data members.
/*Beginning of objectSize.cpp*/
#include<iostream.h>
struct A
{
char a;
int b;
float c;
};

class B //a class with the same data Output


members 9
{ 9
char a;
int b;
float c;
};
void main()
{
cout<<sizeof(A)<<endl<<sizeof(B)<<endl;
}
Scope Resolution Operator
It is possible and usually necessary for the library programmer to define the
member functions outside their respective classes. The scope resolution operator
makes this possible.

void Distance::setFeet(int x) //definition


{
class Distance iFeet=x;
{ }
int Distance::getFeet() //definition
int iFeet;
{
float fInches; return iFeet;
public: }
void setFeet(int); //prototypeonly void Distance::setInches(float y)
int getFeet(); //prototype only //definition
void setInches(float); //prototype {
only fInches=y;
float getInches(); //prototypeonly }
float Distance::getInches() //definition
};
{
return fInches;
}
Contd…
We can observe that the member functions have been only prototyped within
the class; they have been defined outside.
The scope resolution operator signifies the class to which they belong.
The class name is specified on the left-hand side of the scope resolution
operator.
Creating Libraries Using the Scope Resolution Operator

Its a three-stepprocess
Step 1: Place the class definition in a header file.
/*Beginning of Distance.h*/
/*Header file containing the definition of the Distance class*/
class Distance
{
int iFeet;
float fInches;
public:
void setFeet(int); //prototype only
int getFeet(); //prototype only
void setInches(float); //prototype only
float getInches(); //prototype only
};
/*End of Distance.h*/
Contd…
Step 2: Place the definitions of the member functions in a C++ source file (the library source code).
A file that contains definitions of the member functions of a class is known as the
implementation file of that class. Compile this implementation file and put in a library.
/*Beginning of Distlib.cpp*/
/*Implementation file for the class Distance*/
#include“Distance.h”
void Distance::setFeet(int x) //definition
{
iFeet=x;
}
int Distance::getFeet() //definition
{
return iFeet;
}
void Distance::setInches(float y) //definition
{
fInches=y;
}
float Distance::getInches() //definition
{
return fInches;
}
/*End of Distlib.cpp*/
Contd…
Step 3: Provide the header file and the library, in
whatever media, to other programmers who want to use
this new data type.
Using Classes in Application Programs
Step 1: Include the header file provided by the library programmer in their
source code.
/*Beginning of Distmain.cpp*/
#include“Distance.h”
void main()
{
....
....
}
/*End of Distmain.cpp*/
Step 2: Declare variables of the new data type in their source code.
#include“Distance.h”
void main()
{
Distance d1,d2;
....
....
}
/*End of Distmain.cpp*/
Contd…

Step 3: Embed calls to the associated functions by passing


these variables in their source code.

/*Beginning of Distmain.cpp*/
/*A sample driver program for creating and using objects of the class
Distance*/
#include<iostream.h>
#include“Distance.h”
void main()
{
Distance d1,d2;
d1.setFeet(2);
d1.setInches(2.2);
d2.setFeet(3);
d2.setInches(3.3);
cout<<d1.getFeet()<<“ ”<<d1.getInches()<<endl;
cout<<d2.getFeet()<<“ ”<<d2.getInches()<<endl;
}
/*End of Distmain.cpp*/
Contd…
Step 4: Compile the source code to get the object file.
Step 5: Link the object file with the library provided by
the library programmer to get the executable or
another library.
this Pointer
The facility to create and call member functions of class objects is provided by
the C++ compiler.
The compiler does this by using a unique pointer known as the this pointer.
The this pointer is always a constant pointer.The this pointer always points
at the object with respect to which the function was called.
After the compiler has ascertained that no attempt has been made to access the
private members of an object by non-member functions, it converts the C++
code into an ordinary C language code as follows:
1. It converts the class into a structure with only data members as follows.
Before After

class Distance
{
int iFeet; struct Distance
float fInches; {
public: int iFeet;
void setFeet(int); //prototype only float fInches;
int getFeet(); //prototype only };
void setInches(float); //prototype only
float getInches(); //prototype only
};
Contd…
2. It puts a declaration of the this pointer as a leading formal argument in the
prototypes of all member functions as follows.
Before
void setFeet(int);
After
void setFeet(Distance * const,int);
Before
int getFeet();
After
int getFeet(Distance * const);
Before
void setInches(float);
After
void setInches(Distance * const,float);
Before
float getInches();
After
float getInches(Distance * const);
Contd…
3. It puts the definition of the this pointer as a leading formal argument in the
definitions of all member functions as follows.
It also modifies all the statements to access object members by accessing them
through the this pointer using the pointer-to-member access operator (->).
Before After
void Distance::setFeet(int x) void setFeet(Distance * const this, int x)
{ {
iFeet=x; this->iFeet=x;
} }

Before After
int Distance::getFeet() int getFeet(Distance * const this)
{ {
return iFeet; return this->iFeet;
} }
Contd…

Before After
float Distance::getInches() float getInches(Distance * const this)
{ {
return fInches; return this->fInches;
} }

The scope resolution operator is also an operator. Just like any other operator,
it operates upon its operands.
The scope resolution operator is abinary operator,thatis,ittakes two operands.
Based upon this information, the scope resolution operator inserts a constant
operator of the correct type as a leading formal argument to the function on its
right.
For example, if the class name is Distance, as in the above case, the compiler
inserts a pointer of type Distance * const as a leading formal argument to the
function on its right.
Contd…
4. It passes the address of invoking object as a leading parameter to each call to
the member functions as follows.

Before After
d1.setFeet(1); setFeet(&d1,1);

Before After
d1.setInches(1.1); setInches(&d1,1.1);

Before After
cout<<d1.getFeet()<<endl; cout<<getFeet(&d1)<<endl;

Before After
cout<<d1.getInches()<<endl; cout<<getInches(&d1)<<endl;
Contd…
It is evident that the this pointer should continue to point at the same object—
the object with respect to which the member function has been called—
throughout its lifetime. For this reason, the compiler creates it as aconstant
pointer.

/*Beginning of Distlib.cpp*/
#include“Distance.h”
/*Beginning of Distance.h*/ Distance Distance::add(Distance dd)
class Distance {
{ Distance temp;
/* temp.iFeet=iFeet+dd.iFeet; //legalto access both
rest of the class Distance //temp.iFeet and dd.iFeet
temp.fInches=fInches+dd.fInches; //ditto
*/ return temp;
Distance add(Distance); }
}; /*
/*End of Distance.h*/ definitions of the rest of the functions of class
Distance
*/
/*End of Distlib.cpp*/
Contd…
Ooooooooooooooooooooooooooooooooooo
o
/*Beginning of Distmain.cpp*/
#include<iostream.h>
#include“Distance.h”
void main()
{
Distance d1,d2,d3;
d1.setFeet(1);
d1.setInches(1.1);
d2.setFeet(2);
d2.setInches(2.2);
d3=d1.add(d2);
cout<<d3.getFeet()<<“’-”<<d3.getInches()<<“’’\n”;
}

/*End of Distmain.cpp*/
Outpu
t 3-
3.3
Contd...
The definition of Distance :: add() function, after the previously described conversion by
the compiler is carried out, will appear as follows.
Distance add(Distance * const this, Distance dd)
{
Distance temp;
temp.iFeet=this->iFeet+dd.iFeet;
temp.fInches=this->fInches+dd.fInches;
return temp;
}
When this function is called from the main() function with respect to ‘d1’, the this
pointer points at ‘d1’. Thus, it is the private data member of ‘d1’ that is being accessed
in the second and third lines of the add() function.
So, now we can
▪ Declare a class
▪ Define member data and member functions
▪ Make members private and public
▪ Declare objects and call member functions with respect to objects
Contd…
Once again, the importance of compile-time errors over run-time errors is
emphasized.
A pure C compiler would not recognize this statement as an invalidaccess.
Thus, creating bug-free executables is difficult and unreliable in C. This is due to the
absence of language constructs that enforce data security.
On the other hand, a C++ compiler that also detects invalid access of private
data members would immediately throw an error during compile time itself and
prevent the creation of the executable.Thus, creating bug-free executables is easier
and more reliable in C++ than in C.This is due to the presence of language constructs
that enforce data security.
Data Abstraction

Data abstraction is a virtue by which an object hides its internal operations from the rest
of the program.
It makes it unnecessary for the client programs to know how the data is internally
arranged in the object.
Now, in order to understand this concept, let us take an example in C++.The library
programmer, who has designed the Distance class, wants to ensure that the fInches portion
of an object of the class should never exceed 12
Example
If a value larger than 12 is specified by an application programmer while calling
the Distance::setInches() function, the logic incorporated within the definition of
the function should automatically increment the value of iFeet and
decrement the value of fInches by suitable amounts.
void Distance::setInches(float y)
{
fInches=y;
if(fInches>=12)
{
iFeet+=fInches/12;
fInches-=((int)fInches/12)*12;
}
}
Here, we notice that an application programmer need not send values less than 12 while
calling the Distance::setInches() function. The default logic within the
Distance::setInches() function does the necessary adjustments. This is an example of data
abstraction.
Contd…
Similarly, the definition of the Distance::add() function should also be modified as
follows by the library programmer. Here, it can be assumed that the value of
fInches portion of neither the invoking object nor the object appearing as formal
argument (‘dd’) can be greater than 12.

Distance Distance::add(Distance dd)


d1.setFeet(1);
{
d1.setInches(9.5);
Distance temp;
d2.setFeet(2);
temp.iFeet=iFeet+dd.iFeet;
d2.setInches(5.5);
temp.setInches(fInches+dd.fInches);
d3=d1.add(d2);
return temp;
}

then the value of d3.fInches will become 3 (not 15) and the value of d3.iFeet will become
4 (not 3).
Contd…
It has already been mentioned that real-world objects never attain an invalid
state.They also do not start in an invalid state.
Let us continue with our earlier example—the Distance class. Recollect that it is
the library programmer’s intention to ensure that the value of fInches portion
of none of the objects of the class Distance should exceed 12.
/*Beginning of DistJunk.cpp*/
#include<iostream.h>
#include“Distance.h”
void main()
{
Distance d1;
cout<<d1.getFeet()<<“ ”<<d1.getInches()<<endl;
}
/*End of DistJunk.cpp*/ Output
297 34.56
Contd…
As you can see, the value of fInches of ‘d1’is larger than 12! This happened
because the value of both iFeet and fInches automatically got set to junk values
when ‘d1’ was allocated memory and the junk value is larger than 12 for
d1.fInches.
Thus, the objective of the library programmer to keep the value of fInches less
than 12 has not yet been achieved.
It would be unrealistic to expect that an application programmer will explicitly
initialize each object that is declared.
Distance d1;
d1.setFeet(0); //initialization
d1.setInches(0.0); //initialization
Data abstractionis effectivedue todata hidingonly.
On the other side of the coin, in C language, life becomes difficult for an
application programmer also. If a certain member of a structure variable acquires
an invalid or a wrong value, he/she has to hunt through the entire source code
to detect the bug.
Perfect definitions of the member functions are guaranteed to achieve their objective
because ofdata hiding.
Explicit Address Manipulation
An application programmer can manipulate the member data of any object by
explicit address manipulation.
/*Beginning of DistAddrManip.cpp*/
#include“Distance.h”
#include<iostream.h>
void main()
{
Distance d1;
d1.setFeet(256);
d1.setInches(2.2);
char * p=(char *)&d1; //explicit address manipulation
*p=1; //undesirable but unpreventable
cout<<d1.getFeet()<<“ ”<<d1.getInches()<<endl;
}
/*End of DistAddrManip.cpp*/
However, such explicit address manipulation by an application programmer cannot
be prevented.
Arrow Operator
Member functions can be called with respect to an object through a pointer
pointing at the object.
The arrow operator (->) does this.

/*Beginning of PointerToMember.cpp*/
#include<iostream.h>
#include“Distance.h”
void main()
{
Distance d1; //object
Distance * dPtr; //pointer
dPtr=&d1; //pointer initialized
/*Same as d1.setFeet(1) and d1.setInches(1.1)*/
dPtr->setFeet(1); //calling member functions
dPtr->setInches(1.1); //through pointers
/*Same as d1.getFeet() and d1.getInches()*/
cout<<dPtr->getFeet()<<“ ”<<dPtr->getInches()<<endl;
}
/*End of PointerToMember.cpp*/
Contd…
It is interesting to note that just like the dot (.) operator, the definition of the arrow
(->) operator has also been extended in C++.
It takes not only data members on its right as in C, but also member
functions as its right-hand side operand.
If the operand on its right is a data member, then the arrow operator behaves
just as it does in C language.
However, if it is a member function of a class where a pointer of the same class
type is its left-hand side operand, then the compiler simply passes the value of
the pointer as an implicit leading parameter to the function call.

dPtr->setFeet(1); setFeet(dPtr,1);
Now, the value of dPtr is copied into the this pointer.Therefore, the this pointer
also points at the same object at which dPtr points.
Calling One Member Function from Another

One member function can be called from another.

/*Beginning of NestedCall.cpp*/
class A
{
int x;
public: void main()
void setx(int); {
A A1;
void setxindirect(int);
A1.setxindirect(1);
}; }
void A::setx(int p) /*End of NestedCall.cpp*/
{
x=p;
}
void A::setxindirect(int q)
{
setx(q);
}
Contd…
The call to the A::setxindirect() function changes from
A1.setxindirect(1);
to
setxindirect(&A1,1);
The definition of the A::setxindirect() function changes from
void A:: setxindirect(int q)
{
setx(q);
}
to
void setxindirect(A * const this, int q)
{
this->setx(q); //calling function through a pointer
}
Contd…

which, in turn, changes to


void setxindirect(A * const this, int q)
{
setx(this,q); //action of arrow operator
}
Member Functions and Member Data
Overloaded Member Functions: Member functions can be overloadedjust
like non-member functions.

void A::show()
#include<iostream.h> {
class A cout<<“Hello\n”;
{ }
public: void A::show(int x)
void show(); {
void show(int); for(int i=0;i<x;i++)
}; cout<<“Hello\n”;
}
void main()
{
A A1;
A1.show(); //first definitioncalled
A1.show(3); //second definition called
}
Contd…
Consider the following example

classA
{
public:
void show();
};
class B
{
public:
void show();
};

A function of the same name show() is defined in both the classes—‘A’ and ‘B’.The
signature also appears to be the same.
But with our knowledge of the this pointer, we know that the signatures are actually different.

void show(A * const);


void show(B * const);
Contd..
Without the facility of function overloading, it would not be possible for us to
have two functions of the same name in different classes.
Without the facility of function overloading, choice of names for member
functions would become more and more restricted.
Hence C++ enlabes with the concept of Dynamic Polymorphism.

Default Values for Formal Arguments of Member Functions – Over


Page no: 65 from Sourav Sahay
Inline Member Functions – Over Page no: 66 from Sourav Sahay
Example
#include<iostream.h>
class A
{
public:
void show(int=1);
};
void A::show(int p)
{
for(int i=0;i<p;i++)
cout<<“Hello\n”;
}
void main()
{
A A1;
A1.show(); //default value taken
A1.show(3); //default value overridden
}
/*End of memFuncDefault.cpp*/
Constant Member Functions
Let us consider this situation. The library programmer desires that one of the
member functions of his/her class should not be able to change the value of
member data.
This function should be able to merely read the values contained in the data
members, but not change them.
However, he/she fears that while defining the function he/she might accidentally
write the code to do so.
In order to prevent this, he/she seeks the compiler’s help. If he/she declares the
function as a constantfunction.
And thereafter attempts to change the value of a data member through the
function, the compiler throws an error.
Let us consider the class Distance. The Distance::getFeet(),
Distance::getInches(), and the Distance::add() functions should obviously be
constant functions. They should not change the values of iFeet or fInches
members of the invoking object even by accident.
Member functions are specified as constants by suffixing the prototype and the
function definition headerwith the constkeyword.
Example
/*Beginning of Distlib.cpp*/
/*Implementation file for the class Distance*/
#include“Distance.h”
void Distance::setFeet(int x)
/*Header file containing the definition of the {
iFeet=x;
Distance }
class*/ Int Distance::getFeet() const //constant function
class Distance {
iFeet++; //ERRO R!!
{ return iFeet;
int iFeet; }
float fInches; void Distance::setInches(float y)
{
public: fInches=y;
void setFeet(int); }
int getFeet() const; //constant function float Distance::getInches() const //constant function
{
void setInches(float); fInches=0.0; //ERRO R!!
float getInches() const; //constant func return fInches;
Distance add(Distance) const; //constant fun }
Distance Distance::add(Distance dd) const //constant function
}; {
/*End of Distance.h*/ Distance temp;
temp.iFeet=iFeet+dd.iFeet;
temp.setInches(fInches+dd.fInches);
iFeet++; //ERRO R!!
return temp;
}
/*End of Distlib.cpp*/
Contd…
For constant member functions, the this pointer becomes ‘a constant pointer to a
constant’ instead of only ‘a constantpointer’.
For example, the this pointer is of type const Distance * const.
Mutable Data Members
A mutable data member is never constant. It can be modified inside constant functions also.
Prefixing the declaration of a data member with the keyword mutable makes it mutable.
/*Beginning of mutable.h*/
classA
{
int x; //non-mutable data member
mutable int y; //mutable data member
public:
void abc() const //a constant member function
{
x++; //ERROR: cannot modify a non-constant data member in a constant member function
y++; //OK: can modify a mutable data member in a constant memberfunction
}
void def() //a non-constant member function
{
x++; //OK: can modify a non-constant data member in a non-constant memberfunction
y++; //OK: can modify a mutable data member in a non-constant memberfunction
}
};
/*End of mutable.h*/
Friends
A class can have global non-member functions and member functions of other
classes as friends.
Such functions can directly access the private data members of objects of the
class.
Friend non-member functions: A friend function is a non-member function that has
special rights to access private data members of any object of the class of whom it is a
friend.
A friend function is prototyped within the definition of the class of which it is
intended to be a friend.The prototype is prefixed with the keyword friend.
Since it is a non-member function, it is defined without using the scope resolution
operator.
Example
/*Beginning of friend.cpp*/
class A
{
int x;
public:
friend void abc(A&); //prototype of the friend function
};
void abc(A& AObj) //definition of the friend function
{
AObj.x++; //accessing private members of the object
}
void main()
{
A A1;
abc(A1);
}
/*End of friend.cpp*/
Contd…
A few points about the friend functions that we must keep in mind are as
follows:
1) friend keyword should appear in the prototype only and not in the definition.
2) Since it is a non-member function of the class of which it is a friend, it can be
prototyped in either the private or the public section of the class.
3)A friend function takes one extra parameter as compared to a member function
that performs the same task. This is because it cannot be called with respect to
any object. Instead, the object itself appears as an explicit parameter in the
function call.
4)We need not and should not use the scope resolution operator while defining a
friend function.
There are situations where a function that needs to access the private data
members of the objects of a class cannot be called with respect to an object of
the class.
In such situations, the function must be declared as a friend.
Friend classes
A class can be a friend of another class.
Member functions of a friend class can access private data members of objects of the
class of which it is afriend.
If class B is to be made a friend of class A, then the statement
friend class B;
should be written within the definition of class A.
class A
{
friend class B; //declaring B as a friend of A
/*
rest of the classA
*/
};
It does not matter whether the statement declaring class B as a friend is mentioned
within the private or the public section of class A. Now, member functions of
class B can access the private data members of objects of class A
Example
/*Beginning of friendClass.cpp*/
class B; //forward declaration… necessary because
//definition of class B is after the statement
//that declares class B a friend of classA.
classA
{
int x;
public:
void setx(const int=0);
int getx( ) const;
friend class B; //declaring B as a friend ofA
};
class B
{
A *APtr;
public: As we can see, member
void Map(A * const); functions of class B are able
void test_friend(const int);
}; to access private data
void B::Map(A * const p) member of objects of the
{ class A although they are
APtr = p;
}
not member functions of
void B::test_friend(const int i) classA.
{
APtr->x=i; //accessing the private data member
}
/*End of friendClass.cpp*/
Contd…
Friendship is not transitive.
class B;
class C;
/*Beginning of friendTran.cpp*/
class A
{
friend class B;
int a;
};
class B
{
friend class C;
};
class C
{
void f(A * p)
{
p->a++; //error: C is not a friend ofA
//despite being a friend of afriend
}
};
/*End of friendTran.cpp*/
Friend member functions
How can we make some specific member functions of one class friendly to
another class? For making only
B::test_friend() function a friend of class A, replace the line friend class B; in
the declaration of the class A with the line
friend void B::test_friend();
The modified definition of the class A is
classA
{
/*
rest of the class A
*/
friend void B::test_friend();
};
However, in order to compile this code successfully, the compiler should first see the
definition of the class B.
Otherwise, it does not know that test_friend() is a member function of the class B.
Contd…
However, a pointer of type A * is a private data member of class B.
So, the compiler should also know that there is a class A before it compiles the
definition of class B.
This problem of circular dependence is solved by forward declaration.

class A;
class B
{
A *APtr;
public:
void Map(const A * const);
void test_friend(const int=0);
};
class A
{
int x;
public:
friend void B::test_friend(const int=0);
};
/*End of friendMemFunc.h*/
Contd…
Another problem arises if we try to define the B::test_friend() function as an
inline function by defining it within class B itself.

But how will the code inside


class B B::test_friend() function compile?
{
/* The compiler will not know that there is
rest of the class B a data member ‘x’ inside the definition of
*/ classA.
public:
void test_friend(const int p) For overcoming this problem, merely
{ prototype B::test_friend() function
APtr->x=p; //will not compile within class B;
}
}; define it as inline after the definition of
class A in the header file itself.The
Contd…
/*Beginning of friendMemFuncInline.h*/
classA;
class B
{
A *APtr;
public:
void Map(const A * const);
void test_friend(const int=0);
};
class A
{
int x;
public:
friend void B::test_friend(const int=0);
};
inline void B::test_friend(const int p)
{
APtr->x=p;
}
/*End of friendMemFuncInline.h*/
Friends as bridges
Friend functions can be used as bridges between two classes.
Suppose there are two unrelated classes whose private data members need a
simultaneous update through a common function. This function should be
declared as afriend to both the classes.

class B; //forward declaration


class A
{
/*
rest of the class A
*/
friend void ab(const A&,const B&);
};

class B
{
/*
rest of the class B
*/
friend void ab(const A&,const B&);
};
Static Members
Static member data: Static data members hold global data that is common to all
objects of the class. Examples of such global data are
1) count of objects currently present,
2) common data accessed by all objects, etc.
Let us consider class Account. We want all objects of this class to calculate
interest at the rate of say 4.5%. Therefore, this data should be globally available to
all objects of this class.
This data cannot and should not be a member of the objects themselves.
Otherwise, multiple copies of this data will be embedded within the objects taking
up unnecessary space.
Same value would have to be maintained for this data in all objects.This is very
difficult.Thus, this data cannot be stored in amember variable of classAccount.
At the same time, this data should not be stored in a global variable. Then the data
is liable to be changed by even non-member functions. It will also potentially lead
to name conflicts.
O H H H H H H H H … … … … … … … … Now howthis conflict can be resolved??
Contd…
Storing the data in a static variable of the class resolves this conflict.
Static data members are members of the class and not of any object of the class, that is, they are
not contained inside any object.
We prefix the declaration of a variable within the class definition with the keyword static to
make it a static data member of the class.

/*Beginning of Account.h*/
class Account
{
static float interest_rate; //a static data member
/*
rest of the class Account
*/
};
/*End of Account.h*/

A statement declaring a static data member inside a class will obviously not cause any memory
to get allocated for it.
Moreover, memory for a static data member will not get allocated when objects of the class are
declared.
This is because a static data member is not a member of any object.Therefore, we must not
forget to write the statement to define (allocate memory for) a static member variable.
Contd…
Explicitly defining a static data member outside the class is necessary. Otherwise,
the linker produces an error.
The following statement allocates memory for interest_rate member of class
Account.
floatAccount::interest_rate;
The above statement initializes interest_rate to zero. If some other initial value
(say 4.5) is desired instead, the statement should be rewritten as follows.
floatAccount::interest_rate=4.5;
Static data members should be defined in the implementation files only. The
header file is included in both the implementation file and the driver program.
Making static data members private prevents any change from non-member
functions as only member functions can change the values of static data
members.
Introducing static data members does not increase the size of objects of the
class. Static data members are not contained within objects.There is only one
copy of the static data member in the memory.
Example
Static data members can be of any type.

/*Beginning of Account.h*/
/*Beginning of staticSize.cpp*/ class Account
#include<iostream.h> class A {
{ static float interest_rate;
int x; char y; static char name[30];
float z; /*
static float s; rest of the class Account
*/
};
};
float A::s=1.1; void /*End of Account.h*/
main()
{
cout<<sizeof(A)<<endl; /*Beginning of Account.cpp*/
} #include“Account.h”
/*End of staticSize.cpp*/ float A::interest_rate=4.5;
char A::name[30]=“The Rich and Poor Bank”;
/*
definitions of the rest of the functions of class Account
*/
/*End of Account.cpp*/
Example
/*Beginning ofAccount.h*/
class Account
{
static int nameLength=30;
static char name[nameLength];
/*
rest of the class Account
*/
};

/*End ofAccount.h*/
/*Beginning ofAccount.cpp*/
#include“Account.h”
int A::nameLength;
char A::name[nameLength]=“The Rich and Poor Bank”;
/*
definitions of the rest of the functions of class Account
*/
/*End ofAccount.cpp*/
the variable nameLength is referred to directly without the class name and the scope resolution operator
while defining the variable name. One static data member can directly refer to another without using the
scope resolution operator.
Contd…
We must notice that the static data member that has been initialized inside the
class must be still defined outside the class to allocate memory for it.
Non-integral static data members cannot be initialized like this.
/*Beginning of Account.h*/
class Account
{
static char name[30]=“The Rich and Poor Bank”; //error!!
/*
rest of the classAccount
*/
};
/*End ofAccount.h*/
Contd…
Member functions can refer to static data members directly.

/*Beginning ofAccount.h*/
#include“Account.h”
classAccount
float Account::interest_rate=4.5;
{ void Account::updateBalance()
static float interest_rate; {
public: if(end_of_year)
void updateBalance();
/* balance+=balance*interest_rate/100;
rest of the class Account }
*/ /*
definitions of the rest of the functions of
};
classAccount
/*End ofAccount.h*/ */
/*Beginning ofAccount.cpp*/ /*End of Account.cpp*/
Contd…
The object-to-member access operator can be used to refer to the static data
member of a class with respect to an object.
The class name with the scope resolution operator can do this directly.
f=a1.interest_rate; //a1is an object of the class Account
f=Account::interest_rate;
There are some things static data members can do but non-static data members
cannot.
1)A static data member can be of the same type as the class of which it is a member.
class A
{
static A A1; //OK :static
A * APtr; //OK :pointer
A A2; //ERROR!! :non-static
};
A static data member can appear as the default value for the formal arguments of member
functions of its class.
Contd…
classA
{
static int x;
int y;
public:
void abc(int=x); //OK
void def(int=y); //ERROR!! :object required
};
A static data member can be declared to be a constant. In that case, the member functions
will be able to only read it but not modify its value.
Static member functions :
How do we create a member function that need not be called with respect to an existing object?
This function’s sole purpose is to access and/or modify static data members of the class.
Static member functions fulfill the above criteria.
Prefixing the function prototype with the keyword static specifies it as a static member
function. However, the keyword static should not reappear in the definition of the function.
Contd…
Suppose there is a function set_interest_rate() that sets the value of the
interest_rate static data member of class Account.
The application programmer should be able to call this function even if no objects
have been declared. As discussed previously, this function should be static.

/*Beginning of Account.h*/
classAccount
{
static float interest_rate;
public:
static void set_interest_rate(float);
/*
rest of the class Account
*/
};
/*End of Account.h*/
/*Beginning of Account.cpp*/
#include“Account.h”
float Account::interest_rate = 4.5;
void Account::set_interest_rate(float p)
{
interest_rate=p;
}
/*
definitions of the rest of the functions of class Account
*/
/*End of Account.cpp*/
Objects and Functions
Objects can appear as local variables inside functions.They can also be passed by value or
by reference to functions.

/*Beginning of Distance.h*/
class Distance /*End of Distance.cpp*/
/*Beginning of Distance.cpp*/
{ /*Beginning of Distmain.cpp*/
#include“Distance.h”
public: #include<iostream.h>
Distance Distance::add(Distance dd)
/*function to add the #include“Distance.h”
{
invoking object with void main()
Distance temp;
another {
temp.iFeet=iFeet+dd.iFeet;
object passed as a Distance d1,d2,d3;
temp.setInches(fInches+dd.fInches);
parameter and return the d1.setFeet(5);
return temp;
resultant d1.setInches(7.5);
}
object*/ d2.setFeet(3);
/*
d2.setInches(6.25);
definitions of the rest of the
Distance add(Distance); d3=d1.add(d2);
functions of class
/* cout<<d3.getFeet()<<“
Distance
rest of the class Distance ”<<d3.getInches()<<endl;
*/
*/ }
/*End of Distance.cpp*/
}; /*End of Distmain.cpp*/
/*End of Distance.h*/
Contd…
They can be returned by the value or by functions.
Arrays of Objects :
It is possible to create array of objects.
➢ We can have arrays of variables that are of the type class.
Such variables are called arrays of objects.

Ex: class employee


{
char name[20];
Creating array of objects:
float age; employee manager[3]; //array of manager
public: employee worker[75]; //array of worker.
void getdata();
➢ The array of manager contains three objects,
void putdata(); manager[0], manager[1] and manager[2].
}
Contd…
Accessing array of objects
manager[i].getdata();
manager[i].putdata();
Storage of array of objects

Name
Manager[0]
Age
Name
Manager[1]
Age
Name
Manager[2]
Age
Example
#include“Distance.h”
#include<iostream.h>
#define SIZE 3
void main()
{
Distance dArray[SIZE];
int a;
float b;
for(int i=0;i<SIZE;i++)
{
cout<<“Enter the feet :”;
cin>>a;
dArray[i].setFeet(a);
cout<<“Enter the inches :”;
cin>>b;
dArray[i].setInches(b);
}
for(int i=0;i<SIZE;i++)
{
cout <<dArray[i].getFeet()<<“ ” <<dArray[i].getInches()<<endl;
}
}
/*End of DistArray.cpp*/
Arrays inside Objects
➢An array can be declared inside aclass.
➢Such an array becomes a member of all objects of the class.
➢It can be manipulated/accessed by all member functions of the class.
Ex: class example #define SIZE 3
/*A class to duplicate the behaviour of an integer array*/
{ class A
{
int arr[10]; int iArray[SIZE];
public:
------- void setElement(unsigned int,int);
int getElement(unsigned int);
------- };
/*function to write the value passed as second parameter at the position passed
} as first parameter*/
void A::setElement(unsigned int p,int v)
{
if(p>=SIZE)
return; //better to throw an exception
iArray[p]=v;
}
/*function to read the value from the position passed as parameter*/
int A::getElement(unsigned int p)
{
if(p>=SIZE)
return –1; //better to throw an exception
return
Namespaces
Namespaces enable the C++ programmer to prevent pollution of the global
namespace that leads to nameclashes.
The term ‘global namespace’ refers to the entire source code. It also includes all
the directly and indirectly included header files.
By default, the name of each class is visible in the entire source code, that is, in
the global namespace.
It leads to following problems

/*Beginning ofA1.h*/
class A
{
}; Now, let us include both these
/*End ofA1.h*/ header files in a program and
/*Beginning ofA2.h*/ see what happens if we declare
class A //a class with an existing name an object of the class.
{
};
/*End ofA2.h*/
Contd….

/*Beginning of multiDef01.cpp*/
#include”A1.h” The global visibility of
#include”A2.h” the definition of class A makes the
void main() inclusion of the two header files
{ mutually exclusive.
A AObj; //ERROR: Ambiguity error dueto
//multiple definitions of A Consequently, this also makes use of
} the two definitions of class A
/*End of multiDef01.cpp*/ mutually exclusive.

How can this problem be overcome? How can we ensure


that an application is able to use both definitions of class A
simultaneously?
Ans: Enclosing the two definitions of the class in separate
namespaces overcomes this problem.
Contd…

/*Beginning ofA1.h*/
namespace A1 //beginning of a namespace A1 /*Beginning of using.cpp*/
{ #include“A1.h”
class A #include“A2.h”
{ void main()
}; {
} //endof a namespaceA1 using namespace A1;
/*End of A1.h*/ A AObj1; //OK: AObj1 is anobject
/*Beginning ofA2.h*/ of the class defined in
namespace A2 //beginning of a namespace A2 A1.h
{
class A A2::AAObj2; //OK: AObj2 is an
{ object of the class
}; defined in A2.h
} //end of a namespace A2 }
/*End of A2.h*/ /*Beginning of using.cpp*/

Now, the two definitions of the class are enveloped in two different namespaces. The
corresponding namespace, followed by the scope resolution operator, must be prefixed to
the name of the class while referring to it anywhere in the source code. Thus, the
ambiguity encountered in the above listing can be overcome.
Contd…
However, we must note that the using directive brings back the global namespace
pollution that the namespaces mechanism was supposed to remove in the first
place!
The last line in the above listing compiles only because the class name was
qualified by the name of the namespace.
Some namespaces have long names. Qualifying the name of a class that is enclosed
within such anamespace, with the name of the namespace, is cumbersome.

/*Beginning of longName01.cpp*/
namespace a_very_very_long_name
{
class A
{
};
}
void main()
{
a_very_very_long_name::AA1; //cumbersome long name
}
/*End of longName01.cpp*/
Contd…
Assigning a suitably short alias to such a long namespace name solves the problem as
illustrated

/*Beginning of longName02.cpp*/
namespace a_very_very_long_name
{
class A
{
};
}
namespace x = a_very_very_long_name; //declaring an alias
void main()
{
x::A A1; //convenient short name
}
/*End of longName02.cpp*/

Aliases provide an incidental benefit also. Suppose an alias has been used at a number
of places in the source code.
Changing the alias declaration so that it stands as an alias for a different namespace
will make each reference of the enclosed class refer to a completely different class.
Contd…
Suppose an alias X refers to a namespace‘N1’.
namespace X = N1; //declaring an alias
Further, suppose that this alias has been used extensively in the source code.
X::AAObj; //AObj is an object of class A that is enclosed in
namespace N1.
AObj.f1(); //f1() is a member function of the aboveclass.

If the declaration of alias X is modified as follows


namespace X = N2; //modifying the alias
then, all existing qualifications of referred class names that use X would now
refer to class A that is contained in namespace‘N2’.
Nested Inner Classes
A class can be defined inside another class. Such a class is known as a nested
class.
The class that contains the nested class is known as the enclosing class.
Nested classes can be defined in the private, protected, or public portions of
the enclosing class.

/*Beginning of nestPublic.h*/
/*Beginning of nestPrivate.h*/
class A
class A
{
{
public:
class B
class B
{
{
/*
/*
definition of class B
definition of class B
*/
*/
};
};
/*
/*
definition of class A
definition of class A
*/
*/
};
};
/*End of nestPrivate.h*/
/*End of nestPublic.h*/
Contd…
A nested class is created if it does not have any relevance outside its enclosing
class. By defining the class as a nested class, we avoid a namecollision.
In Above Listings ,even if there is a class B defined as a global class, its name will not
clash with the nested class B.

/*Beginning of nestSize.cpp*/
#include<iostream.h>
class A
{
int x;
public:
class B
{
int y;
};
};
void main()
{ Output
cout<<sizeof(int)<<endl; 4
cout<<sizeof(A)<<endl;
4
}
/*End of nestSize.cpp*/
Contd…
Member functions of a nested class can be defined outside the definition of the
enclosing class.
This is done by prefixing the function name with the name of the enclosing class
followed by the scope resolution operator.
This, in turn, is followed by the name of the nested class followed again by the
scope resolution operator.

/*Beginning of nestClassDef.h*/
class A
{
/*Beginning of nestClassDef.cpp*/
public: #include“nestClassDef.h”
class B void A::B::BTest()
{ {
public: //definition of A::B::BTest()function
void BTest(); //prototype only }
}; /*
/*
definition of class A
definitions of the rest of the functions of class B
*/ */
}; /*End of nestClassDef.cpp*/
/*End of nestClassDef.h*/
Contd…
A nested class may be only prototyped within its enclosing class and defined later.
Again, the name of the enclosing class followed by the scope resolution operator
is required.
/*Beginning of nestClassDef.h*/
class A
{
class B; //prototype only
};
class A::B
{
/*
definition of the class B
*/
};
/*End of nestClassDef.h*/
Objects of the nested class are defined outside the member functions of the
enclosing class in much the same way (by using the name of the enclosing class
followed by the scope resolution operator).
A: :BB1;
However, the above line will compile only if class B is defined within the public
section of class A. Otherwise, a compile-time error willresult.
Contd…
An object of the nested class can be used in any of the member functions of the
enclosing class without the scope resolution operator.
Moreover, an object of the nested class can be a member of the enclosing class.
In either case, only the public members of the object can be accessed unless the
enclosing class is a friend of the nested class.

/*Beginning of nestClassObj.h*/
classA /*Beginning of nestClassObj.cpp*/
{ #include“nestClassObj.h”
class B void A::ATest()
{ {
public: B1.BTest();
void BTest(); //prototype only
B B2;
};
B B1; B2.BTest();
public: }
voidATest(); /*End of nestClassObj.cpp*/
};
/*End of nestClassObj.h*/
Contd…
Member functions of the nested class can access the non-static public members
of the enclosing class through an object, a pointer, or a reference only.

/*Beginning of enclClassObj.h*/
classA
#include“enclClassObj.h”
{
public: void A::B::BTest(A&ARef)
void ATest(); {
class B ARef.ATest(); //O K
{ }
public: voidA::B::BTest1()
void BTest(A&); {
void BTest1( ); ATest(); //ERRO R!!
}; }
}; /*End of enclClassObj.cpp*/
/*End of enclClassObj.h*/
}

It can be observed that an error is produced when a direct access is made to a


member of the enclosing class through a function of the nested class.
Constructors and Destructors
Constructors : The constructor gets called automatically for each object
that has just got created. It appears as member function of each class, whether it
is defined or not. It has the same name as that of the class.
It may or may not take parameters.
It does not return anything (not even void).
The prototype of a constructor is
<class name> (<parameter list>);
TYPES OF CONSTRUCTORS:
1) Default Constructor
2) Zero-argument Constructor
3) Parameterized Constructors
4) Explicit Constructors
5) Copy Constructor
Contd…
we want the value of data member fInches of each object of the class Distance
to be between 0.0 and 12.0 at all times within the lifetime of the object.
But this condition may get violated in case an object has just got created.
However, introducing a suitable constructor to the class Distance can enforce
this condition.
The compiler embeds a call to the constructor for each object when it is
created. Suppose aclass A has been declared as follows:

/*Beginning ofA.h*/
/*Beginning ofAMain.cpp*/
classA
#include“A.h”
{
void main()
int x;
{
public:
A A1; //object declared … constructor
void setx(const int=0);
called
int getx();
}
};
/*End ofAMain.cpp*/
/*End ofA.h*/
Contd…
The statement in the function main() is transformed into the following
statements.
A A1; //memory allocated for the object (4 bytes)
A1.A( ); //constructor called implicitly by compiler
The second statement above is then transformed to
A(&A1);
Similarly, the constructor is called for each object that is created dynamically in
the heap by the new operator.
A *APtr;
APtr = new A; //constructor called implicitly by
compiler
The second statement above is transformed into the following two statements.
APtr = new A; //memory allocated
APtr->A( ); //constructor called implicitly by compiler
The second statement above is then transformed into
A(APtr);
Contd…
The foregoing explanations make one thing very clear.
Unlike their name, constructors do not actually allocate memory for objects.
They are member functions that are called for each object immediately after
memory has been allocated for the object.
Contd…

A constructor guarantees that an object created by the class will be initialized automatically.
Contd…
Ex: create an object

integer int1;

➢ Object int1 is created, and also initializes its data members m and n to zero.

➢ There is no need to write any statement to invoke the constructor function.

➢ If a normal member function is defined for zero initialization, we would need to


invoke this function for each of the objects separately.

➢ This would be very inconvenient, if there are a large number of objects.


Contd…
Contd…
Contd…

Default Constructor

➢ Accepts no parameters.

➢ Also called as Zero Constructor.

➢ If no such constructor is defined, then the compiler supplies a default constructor.


Contd…
Parameterized Constructor
➢ A constructor that takes arguments or parameters are called Parameterized
constructors.

➢ We can pass the arguments to constructor function when object are created.
Contd…
➢ We must pass the initial values as arguments to the constructor function when an object is
declared.

➢ This can be done in two ways:

By calling the constructor explicitly.

By calling the constructor implicitly.

By calling the constructor explicitly

integer int1 = integer(10, 100);

➢ This statement creates an integer object int1 and passes the values 10 and 100 to it.

By calling the constructor implicitly

integer int1(10, 100);

➢ Also called as short hand method, shorter, better and easy to implement.
Contd…
Contd…
Copy Constructor

➢ Copy Constructor is used to declare and initialize an object from another object.

➢ Ex:

integer I2 ( I1 );

➢ This would define an object I2 and at the same time initialize it to the values of I1.

➢ Another form:

integer I2 = I1;//it simply assigns the values of I1 to I2, member-by-memeber

➢ The process of initializing through a copy constructor is known as copy initialization.


➢ A copy constructor takes a reference to an object of the same class as itself as an
argument.
Contd… 1. Object declarations:

Multiple Constructors in a Class integer I1;


class integer
- invokes default constructor and set both
{
int m, n; m and n of I1 to 0.
public:
integer() //Default Constructor 2. Object declarations:
{
integer I2(20, 40);
m=0; n=0;
} - invokes parameterized constructor and set
integer(int a, int b) //Parameterized
both m and n of I2 to 20 and 40
Constructor
{ respectively.
m=a; n=b;
} 3. Object declarations:
integer(integer & i) //Copy Constructor
integer I3(I2);
{
m = i.m; n=i.n; - invokes copy constructor which copies
};
}
the values of I2 into I3.
Contd…

The actual parameter, when specified, overrides the default value


Contd…

Default Constructor Default Argument Constructor


A ::A() A :: A(int = 0)

➢ The default argument constructor can be called with either one argument or no
arguments.

➢ When called with no arguments, it becomes a default constructor.


➢ When both these forms are used in a class, it causes ambiguity for a statement such as:
A a;

The ambiguity is whether to call A::A() or A::A(int = 0)


Zero-argument Constructor
We can and should define our own constructors if the need arises. If we do so,
the compiler does not define the constructor.
However, it still embeds implicit calls to the constructor as before.
The constructor is a non-static memberfunction.
It is called for an object. It, therefore, takes the this pointer as a leading formal
argument just like other non-static member functions.
Correspondingly, the address of the invoking object is passed as a leading
parameter to the constructor call. This means that the members of the invoking
object can be accessed from within the definition of the constructor.
Example

/*Beginning of A.cpp*/
#include”A.h”
class A
#include<iostream.h>
{ A::A() //our own constructor
int x; {
public: cout<<”Constructor of class A called\n”;
A(); //our own constructor }
void setx(const int=0); /*
int getx(); definitions of the rest of the functions of class A
}; */
/*End of A.h*/ /*End of A.cpp*/
/*Beginning of AMain.cpp*/
#include<iostream.h>
#include“A.h”
void main()
{
A A1;
cout<<”End of program\n”;
}
/*End of AMain
Destructors
➢ Used to destroy the objects that have been created by a constructor.

➢ The destructor is a member function whose name is the same as the class name
but is preceded by a tilde( ~).

➢ Destructor of class integer can be defined as;

~integer( ) { }

➢ Destructor never takes any argument nor does it return any value.
➢ It will be invoked implicitly by the compiler upon exit from the program to
clean up storage that is no longer accessible. (No need to call it explicitly)

➢ Destructors releases memory space for future use.

➢ Destructors destroy the objects in the reverse order of creation.


Contd…
➢ Whenever new is used to allocate memory in the constructors, we
should use delete to free that memory.

➢ This is required because when the pointers to objects go out of


scope, a destructor is not called implicitly.

➢ Constructors.cpp
➢ Destructors.cpp
➢ DestructoroutofScope.cpp
➢ beforeDestructor.cpp
➢ CopyConstructors.cpp
➢ OverloadedConstructors.cpp
➢ ParameterizedConstructors.cpp
Contd…
Ex: void main( )
{
AA1;
} //A1 goes out of scope here

‘A1’ goes out of scope just before the main() function terminates. At this point, the
compiler embeds a call to the destructor for ‘A1’. It embeds the following statement.
A1.~A(); //destructorcalled
• The destructor will also be called for an object that has been dynamically created in the
heap just before the delete operator is applied on the pointer pointing at it.
A * APtr;
APtr = new A; //object created … constructor called ........
deleteAPtr; //object destroyed … destructor called
The last statement is transformed into
APtr->~A( ); //destructor called for *APtr
deleteAPtr; //memory for *APtr released
Contd…
The destructor does not ‘destroy’ or deallocate memory that an object occupies.
It is merely a member function that is called for each object just before the object
goes out of scope (gets destroyed).
Before
After
classA classA
{ {
....
........ Public:
public: ~A(); //prototype inserted implicitly by compiler
....... ....
};
}; A::~A( )
void main( ) {
//empty definition inserted implicitly by compiler
{
}
A A1; void main( )
} {
A A1;
A1.~A( );
}
Contd…
/*Beginning ofA.h*/
classA
{
int x;
public:
A( ); /*Beginning ofAMain.cpp*/
void setx(const int=0); #include“A.h”
int getx(); #include<iostream.h>
~A( ); //our own destructor
};
void main()
/*End ofA.h*/ {
/*Beginning of A.cpp*/ A A1;
#include“A.h” cout<<“End of program\n”;
#include<iostream.h>
A::A() }
{ /*End ofAMain.cpp*/
cout<<“Constructor of class A called\n”;
}
A::~A() //our own destructor
{
cout<<“Destructor of class A called\n”;
}
/*
definitions of the rest of the functions of class A
*/
/*End ofA.cpp*/
Zero-argument Constructor Example

Output
Constructor of Class A called
End of rogram
Parameterized Constructor

O utput 1 1.1
Introduction to Java
Java Programming Basics
• Java is one of the most popular and widely used programming
language and platform.
• A platform is an environment that helps to develop and run programs
written in any programming language.
• Java is fast, reliable and secure.
• Applications: From desktop to web applications, scientific
supercomputers to gaming consoles, cell phones to the Internet, Java is
used in every nook and corner.
• Java was originally developed by James Gosling at Sun Microsystems
(which has since been acquired by Oracle) and released in 1995 as a
core component of Sun Microsystems' Java platform.
• The original name of this language was Oak.
• Later the project went by the name Green and was finally
renamed Java.
Java’s Magic: The Byte code
• What is Bytecode
• Java program is compiled bytecode is generated.
• To be more precise a Java bytecode is the intermediate code in the
form of a .class file.
• Bytecode in Java is the reason java is platform-independent.
Step by step Execution of Java Program:
• Whenever, a program is written in JAVA, the javac compiles it.
• The result of the JAVA compiler is the .class file or the bytecode and
not the machine native code (unlike C compiler).
• The bytecode generated is a non-executable code and needs an
interpreter to execute on a machine. This interpreter is the JVM and
thus the Bytecode is executed by the JVM.
• And finally program runs to give the desired output.
Java Development Kit
• Three core technology packages
• The JVM(Java Virtual Machine):
• is the Java platform component that executes programs.
• The JRE(Java Runtime Environment):
• is the on-disk part of Java that creates the JVM.
• The JDK(Java Development Kit):
• allows developers to create Java programs that can be executed
and run by the JVM and JRE.
The JDK(Java Development Kit):
• JDK is a collection of tools that are used to create Java programs that
can be executed and run by the JVM and JRE.
• It consists of
• javac-the java compiler that translates the source code to the bytecode
form and stores it in a separate class file.
• java-java interpreter, which interprets the bytecode stored in the class
file and executes the program to generate output.
• javadoc- for creating html document for documentation from source
code file.
• javah-it produces header files for the use of native methods
• jdb- java debugger which helps to find errors in the program
• appletviewer- for executing java applet.
Following are the steps that illustrates
execution process of the application program
• The user creates java source code in the text editor.
• The source is compiled using the javac command.
• javadoc tool can be used to create the HTML files that document the
source program.
• On compiling the source code a class file will get generated which
consists of the bytecode.
• The developer may use javah tool for generating the required header
files.
• The class file produced by javac can be interpreted using java in
order to execute the program.
Java Buzzwords
• Features:
• Simple
• Object Oriented
• Robust:
• Strictly typed language
• Memory management through garbage collection
• Exception handling
• Multithreaded:
• Interactive, networked programs
• Architectural Neutral:
• “Write once, run anywhere, anytime, forever”
• Interpreted and high performance
• Distributed :
• Designed for distributed environment of the internet because it handles TCP/IP
protocol suite.
• Dynamic:
• Dynamically linking new libraries, methods and objects
Object Oriented Programming
There are four main OOP concepts in Java.
These are:
• Abstraction
• Encapsulation
• Inheritance
• Polymorphism
Abstraction
• Abstraction means using simple things to represent complexity.
• Data Abstraction is the property by virtue of which only the essential
details are displayed to the user.
• Abstraction means simple things like objects, classes,
and variables represent more complex underlying code and data.
Encapsulation:
• Binding together the code and the data it manipulates and keeps them safe
from outside interface and misuse.
• Classes, objects, access specifiers
Class & Object
• A class is a user defined blueprint or prototype
• It represents the set of properties or methods that are common to all objects
of one type
• Syntax:
class classname
{
Data members
Member functions
};
• Objects are instances/occurrences of a class.
Inheritance
• It is the mechanism in java by which one class is allowed to inherit the
features(fields and methods) of another class.
• Important terminology:

• Super Class: The class whose features are inherited is known as super class(or a
base class or a parent class).
• Sub Class: The class that inherits the other class is known as sub class(or a
derived class, extended class, or child class). The subclass can add its own fields
and methods in addition to the superclass fields and methods.
• Reusability: Inheritance supports the concept of “reusability”, i.e. when we want
to create a new class and there is already a class that includes some of the code
that we want, we can derive our new class from the existing class. By doing this,
we are reusing the fields and methods of the existing class.
Polymorphism
• The word “poly” means many and “morphs” means forms, So it means
many forms.
• Polymorphism is considered as one of the important features of Object
Oriented Programming.
• Polymorphism allows us to perform a single action in different ways.
• Method Overloading
• Operator Overloading
First Sample Program
• A source file officially is a compilation unit.
• It is a text file that contains one or more class definitions.
• This file use the .java filename extension.
• In java all code must reside inside a class.
• The name of that class should match the name of the file that hold
the program.
• Also the capitalization of filename should match the classname.
Sample Program
• Example:
• Filename: Example.java
/* This is a simple java program.
Call this file “Example.java”. */
class Example
{
// your program begins with a call to main()
public static void main(String args[])
{
system.out.println(“ This is a sample java program”);
}
}
Compiling the program
• Compile the program:
• Command: javac Example.java
• The javac compiler creates a file called Example.class that is the bytecode
version of the program.
• It contains intermediate representation of the program that contains
instructions the JVM will execute.
• Run the program:
• Command: java Example
• When the program is run the following output will be displayed:
This is a simple java program.
Control Statements in Java
• In programming we face some situations where we want a certain
block of code to be executed when some condition is fulfilled.
• A programming language uses control statements to control the flow
of execution of program based on certain conditions.
• In Java, the control statements are divided into three categories which
are selection statements, iteration statements, and jump statements.
Java’s Selection statements:
• if
• if-else
• nested-if
• if-else-if
• switch-case
If statement:
• is the most simple decision making statement.
• It is used to decide whether a certain statement or block of
statements will be executed or not i.e if a certain condition is true
then a block of statement is executed otherwise not.
• Syntax: Flowchart:

if(condition)
{
// Statements to execute if
// condition is true
}
class IfDemo
{
public static void main(String args[])
{
int i = 10;

if (i > 15)
System.out.println("10 is less than 15");

// This statement will be executed


// as if considers one statement by default
System.out.println("I am Not in if");
}
}
Output:

I am Not in if
if-else:
• In if…else statement, if condition is true then statements in if block
will be executed but if it comes out as false then else block will be
executed.
• Syntax: Flowchart:
if (condition)
{
// Executes this block if
// condition is true
}
else
{
// Executes this block if
// condition is false
}
// Java program to illustrate if-else statement
class IfElseDemo
{
public static void main(String args[])
{
int i = 10;

if (i < 15)
System.out.println("i is smaller than 15");
else
System.out.println("i is greater than 15");
}
}
Output:

i is smaller than 15
if-else-if ladder:
• A user can decide among multiple options.
• The if statements are executed from the top down.
• As soon as one of the conditions controlling the if is true, the
statement associated with that if is executed, and the rest of the
ladder is bypassed.
• If none of the conditions is true, then the final else statement will be
executed.
Syntax:

if (condition)
statement;

else if (condition)
statement;
.
.
else
statement;
// Java program to illustrate if-else-if ladder
class ifelseifDemo
{
public static void main(String args[])
{
int i = 20;

if (i == 10)
System.out.println("i is 10");
else if (i == 15)
System.out.println("i is 15");
else if (i == 20)
System.out.println("i is 20");
else
System.out.println("i is not present");
}
}
Output:

i is 20
nested-if:
• Nested if statements means an if statement inside an if statement i.e,
we can place an if statement inside another if statement.
Syntax:
if (condition1)
{
// Executes when condition1 is true
if (condition2)
{
// Executes when condition2 is true
}
else
{
// Executes when condition2 is false
}
}
else
{
// Executes when condition1 is false
}
switch-case:
• The switch statement is a multiway branch statement.
Syntax:
switch (expression)
{
case value1:
statement1;
break;
case value2:
statement2;
break;
.
.
case valueN:
statementN;
break;
default:
statementDefault;
}
// Java program to illustrate switch-case
class SwitchCaseDemo
{
public static void main(String args[])
{
int i = 9;
switch (i)
{
case 0:
System.out.println("i is zero.");
break;
case 1:
System.out.println("i is one.");
break;
case 2:
System.out.println("i is two.");
break;
default:
System.out.println("i is greater than 2.");
}
}
}
Output:

i is greater than 2.
Looping Statements
• Looping in programming languages is a feature which facilitates the
execution of a set of instructions/functions repeatedly while some
condition evaluates to true.
• while
• do-while
• for
while loop:
• A while loop is a control flow statement that allows code to be executed
repeatedly based on a given Boolean condition.
• While loop starts with the checking of condition. If it evaluated to true, then the
loop body statements are executed otherwise first statement following the loop is
executed. For this reason it is also called Entry control loop

Syntax :
while (boolean
condition)
{
loop statements...
};
// Java program to illustrate while loop
class whileLoopDemo
{
public static void main(String args[])
{
int x = 1;

// Exit when x becomes greater than 4


while (x <= 4)
{
System.out.println("Value of x:" + x);

x++;
}
}
}
Output:

Value of x:1
Value of x:2
Value of x:3
Value of x:4
do while:
• do while loop is similar to while loop with only difference that it
checks for condition after executing the statements, and therefore is
an example of Exit Control Loop.
• do while loop starts with the execution of the statement(s). There is
no checking of any condition for the first time.

Syntax:
do
{
statements..
}
while (condition);
// Java program to illustrate do-while loop
class dowhileloopDemo
{
public static void main(String args[])
{
int x = 21;
do
{
// The line will be printed even
// if the condition is false
System.out.println("Value of x:" + x);
x++;
}
while (x < 20);
}
}
Output:

Value of x: 21
for loop:
• for loop provides a concise way of writing the loop structure. Unlike a
while loop, a for statement consumes the initialization, condition and
increment/decrement in one line.

Syntax:
for (initialization condition;
testing condition;

increment/decrement)
{
statement(s)
}
/ Java program to illustrate for loop.
class forLoopDemo
{
public static void main(String args[])
{
// for loop begins when x=2
// and runs till x <=4
for (int x = 2; x <= 4; x++)
System.out.println("Value of x:" + x);
}
}
Output:

Value of x:2
Value of x:3
Value of x:4
Difference between break and continue
statement
• The break keyword is used to breaks(stopping) a loop execution,
which may be a for loop, while loop, do while.
• The continue keyword is used to skip the particular recursion only in a
loop execution, which may be a for loop, while loop, do while.
Example: Program Output:
class BreakAndContinue
{
public static void main(String args[]) Break Statement
{ ....................
// Illustrating break statement (execution stops when value of i 1
becomes to 4.) 2
System.out.println("Break Statement\n...................."); 3
for(int i=1;i<=5;i++) Continue Statement
{
if(i==4) break;
....................
System.out.println(i); 1
} 2
3
// Illustrating continue statement (execution skipped when value of 5
i becomes to 1.)
System.out.println("Continue Statement\n....................");

for(int i=1;i<=5;i++)
{
if(i==4) continue;
System.out.println(i);
}
}
}
Data types in Java
• Every variable in Java has a data type which tells the compiler what
type of variable it as and what type of data it is going to store.
• Data type specifies the size and type of values.
• Information is stored in computer memory with different data types.
• Whenever a variable is declared, it becomes necessary to define a
data type that what will be the type of data that variable can hold.
Primary Data Type
• Java supports eight primitive datatypes:
• byte, short, int, long, float, double, char and boolean.
• These eight data types are further classified into four groups:
• Integer,
• Relational Numbers(Floating point)
• Characters
• Boolean(Conditional).
Intergers
• Integer is the whole number without any fractional point. It can hold
whole numbers such as 196, -52, 4036, etc.
• Java supports four different types of integers, these are:
Type Width Range
byte 8 bit or -128 to 127
1 byte
short 16 bit or -32,768 to 32767
2 bytes
int 32 bit or -2147,483,648 to 2147,483,647
4 bytes

long 64 bit or -9223,372,036,854,755,808 to 9223,372,036,854,755,807


8 bytes
Floating Point Types
• Also know as real numbers.
• It is used to hold whole numbers containing fractional part such as
36.74, or -23.95.
• There are two types of floating point storage in java.
Type Width Range
float 32 bit or ±1.4E-45 to
4 bytes ±3.40282347E+38F
double 64 bit or ±439E-324 to
8 bytes ±1.7976931348623157E+308
Characters
• It is used to store character constants in memory.
• Java provides a character data type called char.
• Char is 16-bit type or 2 bytes but can hold only a single character.
• Unicode encoding standard is used to represent characters.
Boolean
• Java has a primitive data type called Boolean, for logical values.
• Boolean variables can take either true or false values.
• It is denoted by the keyword boolean and usually consumes one byte
of storage.

Type Contains Size Range


boolean true or false 1 bit true or false
Program: Output:
class DataTypes{ Value Of byte Variable is 5
public static void main(String args[]){ Value Of short Variable is 20
byte byteVar = 5; Value Of int Variable is 30
short shortVar = 20;
Value Of long Variable is 60
int intVar = 30;
long longVar = 60; Value Of float Variable is 20.0
float floatVar = 20; Value Of double Variable is 20.123
double doubleVar = 20.123; Value Of boolean Variable is true
boolean booleanVar = true; Value Of char Variable is W
char charVar ='W';

System.out.println("Value Of byte Variable is " + byteVar);


System.out.println("Value Of short Variable is " + shortVar);
System.out.println("Value Of int Variable is " + intVar);
System.out.println("Value Of long Variable is " + longVar);
System.out.println("Value Of float Variable is " + floatVar);
System.out.println("Value Of double Variable is " + doubleVar);
System.out.println("Value Of boolean Variable is " + booleanVar);
System.out.println("Value Of char Variable is " + charVar);
}
}
Literals
• Any constant value which can be assigned to the variable is called as
literal/constant.
• Integer Literals:
• Decimal literals (Base 10) :
• In this form the allowed digits are 0-9.
• int x = 101;
• Octal literals (Base 8) :
• In this form the allowed digits are 0-7.
• The octal number should be prefix with 0.
• int x = 0146;
• Hexadecimal literals (Base 16)
• In this form the allowed digits are 0-9 and characters are a-f. We can use both uppercase
and lowercase characters.
• The hexa-decimal number should be prefix with 0X or 0x.
• int x = 0X123Face;
• Floating point Lietrals:
• float a = 101.230;
• Character Literals:
• Single quote : We can specify literal to char data type as single character
within single quote.
• char ch = 'a’;
• Escape Sequence : Every escape character can be specified as char literals.
• char ch = '\n';
• String Literals:
• Any sequence of characters within double quotes is treated as String literals.
• "Hello";
• Boolean Literals:
• Only two values are allowed for Boolean literals i.e. true and false.
• boolean b = true;
Variables
• Variables are the identifier of the memory location, which used to
save data temporarily for later use in the program.
• During execution of a program, values can be stored in a variable,
and the stored value can be changed.
• Declaring a Variable:
• Variables has to be declared before it is used.
• Syntax: type variable_name;
• Here's the meaning of type is a data type. It specifies what type of data the
variable will hold.
Dynamic Initialization
• Dynamic means that in Java, you can declare variables anywhere in
the program, because when the statement is executed the memory is
assigned to them.
Scope and Lifetime of a variable
• Java allows variables to be declared within any block.
• A block is begun with an opening curly braces and ended by a closing
curly brace. i.e
{
---
---
}
• The block defines the scope.
• Each time a new block is created a new scope is created.
• Scope defined within a method or by a method
• Scope defined by a method begins with its opening curly braces.
• Variables declared inside the scope are not visible to the code that is
defined outside the code.
Example for Nested Scope:
• Scopes can be nested class scope
{
public static void main(String[] args)
{
int x=10;
if(x==10)
{
int y=20;
system.out.println(“x and y”+x+y);
x=y*2;
}
y=100; // Error! Y not know here
system.out.println(“X is” +x);
}
}
Lifetime of a variable
Variables are created when their scope is entered, and destroyed when
their scope is left.
Thus the lifetime of the variable is defined by its scope
Arrays
• An array is collection of elements of the same data type.
• An array of any type can be created and may have one or more
dimensions.
• A specific elements in an array is accessed by specifying its index
within a square brackets.
• Types of arrays
• One dimensional array
• Multi-dimensional array
One dimensional array
It is a collection of data of same type which is used by a common name.
Syntax:
• datatype identifier[];
• int age[]; or int[] age;
• By using new operator array can be initialized.
• int age[] = new int[5];
• Arrays can be initialized at declaration time also.
• int age[]={22,25,30,32,35};

• Pictorial Representation of an array:


• By using new operator array can be initialized.
Multidimensional Arrays
• Multidimensional Arrays can be defined in simple words as array of arrays.
• Data in multidimensional arrays are stored in tabular form (in row major order).

Declaration:
data_type[][] array_name = new data_type[x][y];
For example: int arr[][] = new int[10][20];

• Size of multidimensional arrays: The total number of elements that can be stored
in a multidimensional array can be calculated by multiplying the size of all the
dimensions.
• For example:
The array int[][] x = new int[10][20] can store a total of (10*20) = 200 elements.
Representation of 2D array in Tabular Format:
• A two – dimensional array can be seen as a table with ‘x’ rows and ‘y’
columns where the row number ranges from 0 to (x-1) and column
number ranges from 0 to (y-1). A two – dimensional array ‘x’ with 3
rows and 3 columns is shown below:
Example 1:
Example 2:
class TwoDArray
class GFG {
{
public static void main(String[] args)
public static void main(String[] args)
{
{
int[][] arr = { { 1, 2 }, { 3, 4 } };
int[][] arr = new int[10][20];
arr[0][0] = 1;
System.out.println("arr[0][0] = " + arr[0][0]);
}
System.out.println("arr[0][0] = " + arr[0][0]);
}
}
}
Output:
Output:
arr[0][0] = 1
arr[0][0] = 1
class TwoDArray
{
Output:
public static void main(String[] args)
{ 0 1
2 3
int arr[][] = new int[4][5];
int i,j,k=0;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
arr[i][j]=k;
k++;
}
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
system.out.println(arr[i][j]+” ”);
system.out.println();
}
}

}
Strings
• String defines an object.
• String type is used to declare string variables.
• Example:
String str=“ this is a sample string”;
System.out.println(str);
Operators: Example:
public class operators
{
public static void main(String[] args)
{
Arithmetic Operators: int a = 20, b = 10, d = 20, e = 40, f = 30;
System.out.println("a + b = " + (a + b));
They are used to perform simple arithmetic System.out.println("a - b = " + (a - b));
operations on primitive data types. System.out.println("a * b = " + (a * b));
* : Multiplication System.out.println("a / b = " + (a / b));
/ : Division System.out.println("a % b = " + (a % b));
% : Modulo
+ : Addition }
– : Subtraction }
Output:
a + b = 30
a - b = 10
a * b = 200
a/b=2
a%b=0
Arithmetic Compound Assignment
Statements
• Assignment operators are used to assign values to variables.
• In the example below, we use the assignment operator (=) to assign
the value 10 to a variable called x:
• int x = 10;
• In many cases assignment operator can be combined with other
operators to build a shorter version of statement called Compound
Statement.
• For example, instead of a = a+5, we can write a += 5.
Increment and Decrement Operator
++ :Increment operator, used for incrementing the value by 1.
• There are two varieties of increment operator.
• Post-Increment : Value is first used for computing the result and then
incremented.
• Pre-Increment : Value is incremented first and then result is computed.
-- : Decrement operator, used for decrementing the value by 1.
• There are two varieties of decrement operator.
• Post-decrement : Value is first used for computing the result and then
decremented.
• Pre-Decrement : Value is decremented first and then result is computed.
Example: Output:
class operators
{
public static void main(String[] args)
{
int a = 20, b = 10, c = 0, d = 20, e = 40;
boolean condition = true;

c = ++a;
System.out.println("Value of c (++a) = " + c); Value of c (++a) = 21

c = b++;
System.out.println("Value of c (b++) = " + c); Value of c (b++) = 10

c = --d;
System.out.println("Value of c (--d) = " + c); Value of c (--d) = 19

c = e--;
System.out.println("Value of c (e--) = " + c); Value of c (e--) = 40

}
}
Bitwise Operators :
• These operators are used to perform manipulation of individual bits
of a number. They can be used with any of the integer types.
• &, Bitwise AND operator: returns bit by bit AND of input values.
• |, Bitwise OR operator: returns bit by bit OR of input values.
• ^, Bitwise XOR operator: returns bit by bit XOR of input values.
• ~, Bitwise Complement Operator: This is a unary operator which
returns the one’s compliment representation of the input value, i.e.
with all bits inversed.
Bitwise OR (|) –
• This operator is binary operator, denoted by ‘|’.
• It returns bit by bit OR of input values, i.e, if either of the bits is 1, it
gives 1, else it gives 0.
For example,
a = 5 = 0101 (In Binary)
b = 7 = 0111 (In Binary)

Bitwise OR Operation of 5 and 7


0101
| 0111
________
0111 = 7 (In decimal)
Bitwise AND (&) –
• This operator is binary operator, denoted by ‘&’.
• It returns bit by bit AND of input values, i.e, if both bits are 1, it gives
1, else it gives 0.
For example,
a = 5 = 0101 (In Binary)
b = 7 = 0111 (In Binary)

Bitwise AND Operation of 5 and 7


0101
& 0111
________
0101 = 5 (In decimal)
Bitwise XOR (^) –
• This operator is binary operator, denoted by ‘^’. It returns bit by bit
XOR of input values, i.e, if corresponding bits are different, it gives 1,
else it gives 0.
For example,
a = 5 = 0101 (In Binary)
b = 7 = 0111 (In Binary)

Bitwise XOR Operation of 5 and 7


0101
^ 0111
________
0010 = 2 (In decimal)
Bitwise Complement (~) –
• This operator is unary operator, denoted by ‘~’.
• It returns the one’s compliment representation of the input value, i.e,
with all bits inversed, means it makes every 0 to 1, and every 1 to 0.
For example,
a = 5 = 0101 (In Binary)

Bitwise Compliment Operation of 5

~ 0101
________
1010 = 10 (In decimal)
Example: Output :
public class operators
{
public static void main(String[] args)
{
int a = 5;
int b = 7;

// bitwise and a&b = 5


// 0101 & 0111=0101 = 5
System.out.println("a&b = " + (a & b));

// bitwise or a|b = 7
// 0101 | 0111=0111 = 7
System.out.println("a|b = " + (a | b));

// bitwise xor
// 0101 ^ 0111=0010 = 2 a^b = 2
System.out.println("a^b = " + (a ^ b));

}
}
Shift Operators:
• These operators are used to shift the bits of a number left or right
thereby multiplying or dividing the number by two respectively.
• They can be used when we have to multiply or divide a number by
two.
General format:
• number shift_op number_of_places_to_shift;
Signed Right shift operator (>>) –
• Shifts the bits of the number to the right.
• The leftmost bit depends on the sign of initial number.
• Similar effect as of dividing the number with some power of two.
For example,
Example 1:
a = 10
a>>1 = 5
Example 2:
a = -10
a>>1 = -5
We preserve the sign bit.
Unsigned Right shift operator (>>>) –
• Shifts the bits of the number to the right and fills 0 on voids left as a
result.
• The leftmost bit is set to 0. (>>>) is unsigned-shift; it’ll insert 0. (>>) is
signed, and will extend the sign bit.
For example,
Example 1:
a = 10
a>>>1 = 5

Example 2:
a = -10
a>>>1 = 2147483643
DOES NOT preserve the sign bit.
Left shift operator (<<) –
• Shifts the bits of the number to the left and fills 0 on voids left as a
result.
• Similar effect as of multiplying the number with some power of two.
For example,
a = 5 = 0000 0101
b = -10 = 1111 0110

a << 1 = 0000 1010 = 10


a << 2 = 0001 0100 = 20

b << 1 = 0000 1010 = -20


b << 2 = 0001 0100 = -40
Relational Operators :
• These operators are used to check for relations like equality, greater than, less than.
• They return Boolean result after the comparison and are extensively used in looping
statements as well as conditional if else statements.
• General format is,
• variable relation_operator value

• Some of the relational operators are-


• ==, Equal to : returns true if left hand side is equal to right hand side.
• !=, Not Equal to : returns true if left hand side is not equal to right hand side.
• <, less than : returns true if left hand side is less than right hand side.
• <=, less than or equal to : returns true if left hand side is less than or equal to right hand
side.
• >, Greater than : returns true if left hand side is greater than right hand side.
• >=, Greater than or equal to: returns true if left hand side is greater than or equal to
right hand side.
Example:
Output:
public class operators
{
public static void main(String[] args)
{
int a = 20, b = 10;
a == b :false
System.out.println("a == b :" + (a == b));
a < b :false
System.out.println("a < b :" + (a < b));
a <= b :false
System.out.println("a <= b :" + (a <= b));
a > b :true
System.out.println("a > b :" + (a > b));
a >= b :true
System.out.println("a >= b :" + (a >= b));
a != b :true
System.out.println("a != b :" + (a != b));

}
}
Logical Operators :
• These operators are used to perform “logical AND” and “logical OR”
operation, i.e. the function similar to AND gate and OR gate in digital
electronics.
• One thing to keep in mind is the second condition is not evaluated if
the first one is false, i.e. it has a short-circuiting effect.
• Used extensively to test for several conditions for making a decision.
• Conditional operators are
• -&&, Logical AND : returns true when both conditions are true.
• ||, Logical OR : returns true if at least one condition is true.
Ternary operator : (?: )
• Ternary operator is a shorthand version of if-else statement.
• It has three operands and hence the name ternary.
• General format is-
• Exp1?Exp2:Exp3
• condition ? if true : if false
• The above statement means that if the condition evaluates to true,
then execute the statements after the ‘?’ else execute the statements
after the ‘:’.
Module 3

•Classes, Inheritance,Exception Handling


Introducing Classes
• The class forms the basis for object-oriented programming in Java.
• Any concept you wish to implement in a Java program must be
encapsulated within a class.
• The most important thing to understand about a class is that it
defines a new data type.
• Once defined, this new type can be used to create objects of that
type.
• Thus, a class is a template for an object, and an object is an instance
of a class.
• Because an object is an instance of a class, you will often see the two
words object and instance used interchangeably.
The General Form of a Class
• Classes will contain data and code.
• A class is declared by use of the class keyword.
• A simplified general form of a class definition is shown here:
class classname
{
type instance-variable1;
type instance-variable2;
// ... type instance-variableN;
type methodname1(parameter-list)
{ // body of method }
type methodname2(parameter-list)
{ // body of method} // ...
type methodnameN(parameter-list)
{ // body of method }
}
• The data, or variables, defined within a class are called instance variables.
• The code is contained within methods.
• Collectively, the methods and variables defined within a class are called
members of the class.
• A Simple Class
• Here is a class called Box that defines three instance variables: width,
height, and depth.
• Currently, Box does not contain any methods
class Box
{
double width;
double height;
double depth;
}
• A class defines a new type of data.
• In this case, the new data type is called Box.
• This name will be used to declare objects of type Box.
• It is important to remember that a class declaration only creates a
template; it does not create an actual object.
• To actually create a Box object, you will use a statement like the
following:
• Box mybox = new Box(); // create a Box object called mybox
• To access these variables and methods, you will use the dot(.)
operator.
• The dot operator links the name of the object with the name of an
instance variable.
• mybox.width = 100;
Sample Program using Box class
Declaring Objects
• Box mybox = new Box();
• This statement combines the two steps. It can be rewritten like this to
show each step more clearly:
• Box mybox; // declare reference to object
• mybox = new Box(); // allocate a Box object.
Review of distinction between a class and an object.

• A class creates a new data type that can be used to create objects.
• That is, a class creates a logical framework that defines the
relationship between its members.
• When you declare an object of a class, you are creating an instance of
that class.
• Thus,a class is a logical construct.
• An object has physical reality. (That is, an object occupies space in
memory.)
Assigning Object Reference Variables
• Box b1 = new Box();
• Box b2 = b1;
• 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.
Introducing Methods
• This is the general form of a method:
type name(parameter-list)
{
// body of method
}
Returning a Value
• 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.
Adding a Method That Takes Parameters
• While some methods don’t need parameters, most do.
• A very simple example of method without parameters .
int square()
{
return 10 * 10;
}
• if you modify the method so that it takes a parameter, as shown next,
int square(int i)
{
return i * i;
}
int x, y;
x = square(5); // x equals 25
x = square(9); // x equals 81
y = 2;
x = square(y); // x equals 4
Constructors
• It can be tedious to initialize all of the variables in a class each time an
instance is created.
• Java allows objects to initialize themselves when they are created.
• This automatic initialization is performed through the use of a constructor.
• It has the same name as the class in which it resides and is syntactically
similar to a method.
• Constructors they have no return type, not even void.
• Once defined, the constructor is automatically called immediately after the
object is created, before the new operator completes.
• A constructor initializes an object immediately upon creation.
Types of constructor
There are two types of constructor in Java:
• Default constructor :
• If we don’t define a constructor in a class, then compiler creates for
the class.
• Default constructor provides the default values to the object like 0,
null, etc. depending on the type.
• And if we write a constructor with arguments or no-arguments then
the compiler does not create a default constructor.
Parameterized Constructor:
• A constructor that has parameters is known as parameterized
constructor.
• If we want to initialize fields of the class with your own values, then
use a parameterized constructor.
The this Keyword
• this can be used inside any method to refer to the current object.
• ‘this’ is a reference variable that refers to the current object.
• Instance Variable Hiding:
Example:
class Test
{
int a;
int b;

Test(int a, int b)
{
this.a = a;
this.b = b;
} Output:
a = 10 b = 20
void display()
{
System.out.println("a = " + a + " b = " + b);
}

public static void main(String[] args)


{
Test T1= new Test(10, 20);
T1.display();
}
}
Garbage Collection
• Since objects are dynamically allocated by using the new operator.
• In some languages, such as C++, dynamically allocated objects must
be manually released by use of a delete operator.
• Java takes a different approach; it handles deallocation for you
automatically.
• The technique that accomplishes this is called garbage collection.
Inheritance
Inheritance
• Inheritance is an important pillar of OOP(Object Oriented Programming).
• It is the mechanism in java by which one class is allow to inherit the
features(fields and methods) of another class.
Important terminology:
• Super Class: The class whose features are inherited is known as super
class(or a base class or a parent class).
• Sub Class: The class that inherits the other class is known as sub class(or a
derived class, extended class, or child class). The subclass can add its own
fields and methods in addition to the superclass fields and methods.
• Reusability: Inheritance supports the concept of “reusability”, i.e. when we
want to create a new class and there is already a class that includes some
of the code that we want, we can derive our new class from the existing
class. By doing this, we are reusing the fields and methods of the existing
class.
• The keyword used for inheritance is extends.

Syntax :
class derived-class extends base-class
{
//methods and fields
}

• Inheritance Basics To inherit a class, you simply incorporate the


definition of one class into another by using the extends keyword.
// A simple example of inheritance. class SimpleInheritance {
// Create a superclass. public static void main(String args[]) {
class A A superOb = new A();
{ B subOb = new B();
int i, j; // The superclass may be used by itself.
void showij() superOb.i = 10;
{ superOb.j = 20;
System.out.println("i and j: " + i + " " + j); System.out.println("Contents of superOb: ");
} superOb.showij();
} /* The subclass has access to all public members of
// Create a subclass by extending class A. its superclass. */
class B extends A subOb.i = 7;
{ subOb.j = 8;
int k; subOb.k = 9;
void showk() System.out.println("Contents of subOb: ");
{ subOb.showij();
System.out.println("k: " + k); subOb.showk();
} System.out.println("Sum of i, j and k in subOb:");
void sum() subOb.sum();
{ }
System.out.println("i+j+k: " + (i+j+k)); }
}
}
The output from this program is shown here:
Contents of superOb:
i and j: 10 20
Contents of subOb:
i and j: 7 8
k: 9
Sum of i, j and k in subOb:
i+j+k: 24
• Even though A is a superclass for B, it is also a completely
independent, stand-alone class.
• Further, a subclass can be a superclass for another subclass.
• You can only specify one superclass for any subclass that you create.
• Java does not support the inheritance of multiple super classes into a
single subclass.
Member Access and Inheritance:
• Although a subclass includes all of the members of its superclass, it
cannot access those members of the superclass that have been
declared as private.
/* In a class hierarchy, private members remain class Access {
private to their class. public static void main(String args[]) {
This program contains an error and will not B subOb = new B();
compile. subOb.setij(10, 12);
*/ subOb.sum();
// Create a superclass. System.out.println("Total is " + subOb.total);
class A { }
int i; // public by default }
void setij(int x, int y) {
i = x;
j = y;
}
private int j; // private to A

}
// A's j is not accessible here.
class B extends A {
int total;
void sum() {
total = i + j; // ERROR, j is not accessible here
}
}
A More Practical Example
// This program uses inheritance to extend Box. // Here, Box is extended to include weight.
class Box class BoxWeight extends Box
{ {
double width; double weight; // weight of box
double height; // constructor for BoxWeight
double depth; BoxWeight(double w, double h, double
// constructor used when all dimensions specified d, double m)
Box(double w, double h, double d) {
{ width = w;
width = w; height = h;
height = h; depth = d;
depth = d; weight = m;
} }
// compute and return volume }
double volume()
{
return width * height * depth;
}
}
class DemoBoxWeight
{
public static void main(String args[])
{
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.println("Weight of mybox1 is " + mybox1.weight);
System.out.println();
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.println("Weight of mybox2 is " + mybox2.weight);
}
}
A Superclass Variable Can Reference a Subclass
Object
• A reference variable of a superclass can be assigned a reference to
any subclass derived from that superclass.
• when a reference to a subclass object is assigned to a superclass
reference variable, you will have access only to those parts of the
object defined by the superclass.
class RefDemo
{
public static void main(String args[])
{
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box();
double vol;
vol = weightbox.volume();
System.out.println("Volume of weightbox is " + vol);
System.out.println("Weight of weightbox is " +weightbox.weight);
System.out.println();

// assign BoxWeight reference to Box reference


plainbox = weightbox;
vol = plainbox.volume(); // OK, volume() defined in Box
System.out.println("Volume of plainbox is " + vol);

/* The following statement is invalid because plainbox does not define a weight member. */
// System.out.println("Weight of plainbox is " + plainbox.weight);
}
}
Using super
• The super keyword refers to superclass (parent) objects.
• The most common use of the super keyword is to eliminate the
confusion between superclasses and subclasses that have methods
with the same name.
• super is used to invoke parent class constructor.
• super can be used to invoke parent class method
• super is used to refer immediate parent class instance variable.
Let’s review the key concepts behind super( )

• When a subclass calls super( ), it is calling the constructor of its


immediate superclass.
• Thus, super( ) always refers to the superclass immediately above the
calling class.
• Also, super( ) must always be the first statement executed inside a
subclass constructor.
Example:
class Animal
{
Animal()
{
System.out.println("animal is created"); Output:
}
} animal is created
class Dog extends Animal dog is created
{
Dog()
{
super();
System.out.println("dog is created");
}
}
class TestSuper3
{
public static void main(String args[])
{
Dog d=new Dog();
}
}
• To see how super( ) is used, consider this improved version of the
BoxWeight( ) class:
// BoxWeight now uses super to initialize its Box attributes.
class BoxWeight extends Box
{
double weight; // weight of box
// initialize width, height, and depth using super()
BoxWeight(double w, double h, double d, double m)
{
super(w, h, d); // call superclass constructor
weight = m;
}
}
Example:
// A complete implementation of BoxWeight. // constructor used when no dimensions specified
class Box Box()
{ {
private double width; width = -1; // use -1 to indicate
private double height; height = -1; // an uninitialized
private double depth; depth = -1; // box
// construct clone of an object }
Box(Box ob) // constructor used when cube is created
{ // pass object to constructor Box(double len)
width = ob.width; {
height = ob.height; width = height = depth = len;
depth = ob.depth; }
} // compute and return volume
// constructor used when all dimensions double volume() {
specified return width * height * depth;
Box(double w, double h, double d) }
{ }
width = w;
height = h;
depth = d;
}
// BoxWeight now fully implements all constructors.
class BoxWeight extends Box // constructor used when cube is created
{ BoxWeight(double len, double m)
double weight; // weight of box {
// construct clone of an object super(len);
BoxWeight(BoxWeight ob) weight = m;
{ // pass object to constructor }
super(ob); }
weight = ob.weight;
}
// constructor when all parameters are specified
BoxWeight(double w, double h, double d, double m)
{
super(w, h, d); // call superclass constructor
weight = m;
}
// default constructor
BoxWeight()
{
super();
weight = -1;
}
class DemoSuper { vol = myclone.volume();
public static void main(String args[]) { System.out.println("Volume of myclone is " + vol);
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3); System.out.println("Weight of myclone is " + myclone.weight);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076); System.out.println();
BoxWeight mybox3 = new BoxWeight(); // default vol = mycube.volume();
BoxWeight mycube = new BoxWeight(3, 2); System.out.println("Volume of mycube is " + vol);
BoxWeight myclone = new BoxWeight(mybox1); System.out.println("Weight of mycube is " + mycube.weight);
double vol; System.out.println();
vol = mybox1.volume(); }
System.out.println("Volume of mybox1 is " + vol); }
System.out.println("Weight of mybox1 is " + mybox1.weight); This program generates the following output:
System.out.println(); Volume of mybox1 is 3000.0
vol = mybox2.volume(); Weight of mybox1 is 34.3
System.out.println("Volume of mybox2 is " + vol); Volume of mybox2 is 24.0
System.out.println("Weight of mybox2 is " + mybox2.weight); Weight of mybox2 is 0.076
System.out.println(); Volume of mybox3 is -1.0
vol = mybox3.volume(); Weight of mybox3 is -1.0
System.out.println("Volume of mybox3 is " + vol); Volume of myclone is 3000.0
System.out.println("Weight of mybox3 is " + mybox3.weight); Weight of myclone is 34.3
System.out.println(); Volume of mycube is 27.0
Weight of mycube is 2.0
A Second Use for super
• The second form of super, that it always refers to the superclass of
the subclass in which it is used.
• This usage has the following general form:
• super.member
• Here, member can be either a method or an instance variable.
• This second form of super is most applicable to situations in which
member names of a subclass hide members by the same name in the
superclass.
// Using super to overcome name hiding.
class A
{
int i;
This program displays the following:
}
i in superclass: 1
// Create a subclass by extending class A.
i in subclass: 2
class B extends A {
int i; // this i hides the i in A
B(int a, int b) {
super.i = a; // i in A
i = b; // i in B
}
void show() {
System.out.println("i in superclass: " + super.i);
System.out.println("i in subclass: " + i);
}
}
class UseSuper {
public static void main(String args[]) {
B subOb = new B(1, 2);
subOb.show();
}
}
Creating a Multilevel Hierarchy
• Up to this point, we have been using simple
class hierarchies that consist of only a
superclass and a subclass.
• However, you can build hierarchies that contain
as many layers of inheritance as you like.
• It is perfectly acceptable to use a subclass as a
superclass of another.
• each subclass inherits all of the traits found in
all of its superclasses.
• In this case, C inherits all aspects of B and A.
Example:
class one
{ public class Main
public void print_geek() {
{ public static void main(String[] args)
System.out.println("Geeks"); {
} three g = new three();
} g.print_geek();
g.print_for();
class two extends one g.print_geek();
{ }
public void print_for() }
{
System.out.println("for"); Output:
}
} Geeks
for
class three extends two Geeks
{
public void print_geek()
{
System.out.println("Geeks");
}
}
class Box class Shipment extends BoxWeight
{ {
private double width; double cost;
private double height; Shipment(double w, double h, double d, double m, double c)
private double depth; {
Box(double w, double h, double d) super(w, h, d, m); // call superclass constructor
{ cost = c;
width = w; height = h; depth = d; }
} class DemoShipment
double volume() {
{ public static void main(String args[])
return width * height * depth; {
} Shipment shipment1 =new Shipment(10, 20, 15, 10, 3.41);
} double vol;
class BoxWeight extends Box vol = shipment1.volume();
{ System.out.println("Volume of shipment1 is " + vol);
double weight; // weight of box System.out.println("Weight of shipment1 is " +
BoxWeight(double w, double h, double d, double m) shipment1.weight);
{ System.out.println("Shipping cost: $" + shipment1.cost);
super(w, h, d); // call superclass constructor }
weight = m;
}
}
MODULE 4
Multithreading programming
Multithreading
• Java provides built-in support for multithreaded programming.
• A multithreaded program contains two or more parts that can run concurrently. Each
part of such a program is called a thread, and each thread defines a separate path of
execution.
• Thus, multithreading is a specialized form of multitasking.
• You are almost certainly acquainted with multitasking, because it is supported by
virtually all modern operating systems.
• There are two distinct types of multitasking.
MULTITASKING

Process-based Thread-based

It is important to understand the difference between the two.


Contd…
• For most readers, process-based multitasking is the more familiar form.
• A process is, in essence, a program that is executing. Thus, process-based
multitasking is the feature that allows your computer to run two or more programs
concurrently.
• For example, process-based multitasking enables you to run the Java compiler at the
same time that you are using a text editor.
• In process based multitasking, a program is the smallest unit of code that can be
dispatched by the scheduler.
• In a thread-based multitasking environment, the thread is the smallest unit of
dispatchable code. This means that a single program can perform two or more tasks
simultaneously.
• For instance, a text editor can format text at the same time that it is printing, as long as
these two actions are being performed by two separate threads.
• Thus, process-based multitasking deals with the “big picture,” and thread-based
multitasking handles the details.
• Multitasking threads require less overhead than multitasking processes. Processes are
heavyweight tasks that require their own separate address spaces.
Contd…
• Interprocess communication is expensive and limited. Context switching from one
process to another is also costly.
• Threads, on the other hand, are lightweight. They share the same address space and
cooperatively share the same heavyweight process.
• Interthread communication is inexpensive, and context switching from one thread
to the next is low cost.
• While Java programs make use of process-based multitasking environments, process-
based multitasking is not under the control of Java. However, multithreaded
multitasking is under the control.
• Multithreading enables you to write very efficient programs that make maximum use
of the CPU, because idle time can be kept to a minimum.
• This is especially important for the interactive, networked environment in which Java
operates, because idle time is common.
• For example, the transmission rate of data over a network is much slower than the rate
at which the computer can process it.
• Even local file system resources are read and written at a much slower pace than they
can be processed by the CPU.
Contd…
• In a single-threaded environment, your program has to wait for each of these tasks to
finish before it can proceed to the next one—even though the CPU is sitting idle most
of the time.
• Multithreading lets you gain access to this idle time and put it to good use.
The Java Thread Model
• The Java run-time system depends on threads for many things, and all the class
libraries are designed with multithreading in mind.
• In fact, Java uses threads to enable the entire environment to be asynchronous.
• This helps reduce inefficiency by preventing the waste of CPU cycles.
• The value of a multithreaded environment is best understood in contrast to its
counterpart. Single-threaded systems use an approach called an event loop with
polling.
• In this model, a single thread of control runs in an infinite loop, polling a single event
queue to decide what to do next.
• Once this polling mechanism returns with, say, a signal that a network file is ready to
be read, then the event loop dispatches control to the appropriate event handler.
• Until this event handler returns, nothing else can happen in the system. This wastes
CPU time.
• It can also result in one part of a program dominating the system and preventing any
other events from being processed.
• In general, in a singled-threaded environment, when a thread blocks (that is, suspends
execution) because it is waiting for some resource, the entire program stops running.
Contd…
• The benefit of Java’s multithreading is that the main loop/polling mechanism is
eliminated.
• One thread can pause without stopping other parts of your program.
• For example, the idle time created when a thread reads data from a network or waits
for user input can be utilized elsewhere.
• Multithreading allows animation loops to sleep for a second between each frame
without causing the whole system to pause. When a thread blocks in a Java program,
only the single thread that is blocked pauses. All other threads continue to run.
•Threads exist in several states.
• A thread can be running.
• It can be ready to run as soon as it gets CPU time. A running thread can be
suspended, which temporarily suspends its activity.
• A suspended thread can then be resumed, allowing it to pick up where it left off. A
thread can be blocked when waiting for a resource.
• At any time, a thread can be terminated, which halts its execution immediately. Once
terminated, a thread cannot be resumed.
Thread Priorities
• Java assigns to each thread a priority that determines how that thread should be treated
with respect to the others.
• Thread priorities are integers that specify the relative priority of one thread to another.
• As an absolute value, a priority is meaningless; a higher-priority thread doesn’t run
any faster than a lower-priority thread if it is the only thread running.
• Instead, a thread’s priority is used to decide when to switch from one running thread
to the next.
• This is called a context switch.
• The rules that determine when a context switch takes place are simple:
• 1) A thread can voluntarily relinquish control : This is done by explicitly yielding,
sleeping, or blocking on pending I/O. In this scenario, all other threads are examined,
and the highest-priority thread that is ready to run is given the CPU.
• 2) A thread can be preempted by a higher-priority thread : In this case, a lower-
priority thread that does not yield the processor is simply preempted—no matter what
it is doing— by a higher-priority thread. This is called preemptive multitasking
Contd…
• In cases where two threads with the same priority are competing for CPU cycles, the
situation is a bit complicated.
• For operating systems such as Windows, threads of equal priority are time-sliced
automatically in round-robin fashion.
• For other types of operating systems, threads of equal priority must voluntarily yield
control to their peers.
Synchronization
• Because multithreading introduces an asynchronous behavior to your programs, there
must be a way for you to enforce synchronicity when you need it.
• For example, if you want two threads to communicate and share a complicated data
structure, such as a linked list, you need some way to ensure that they don’t conflict
with each other.
• That is, you must prevent one thread from writing data while another thread is in the
middle of reading it.
• For this purpose, Java implements an elegant twist on an age-old model of
interprocess synchronization: the monitor.
• The monitor is a control mechanism first defined by C.A.R. Hoare. You can think of a
monitor as a very small box that can hold only one thread.
• Once a thread enters a monitor, all other threads must wait until that thread exits the
monitor. In this way, a monitor can be used to protect a shared asset from being
manipulated by more than one thread at a time.
• Most multithreaded systems expose monitors as objects that your program must
explicitly acquire and manipulate. Java provides a cleaner solution.
• There is no class “Monitor”; instead, each object has its own implicit monitor that is
automatically entered when one of the object’s synchronized methods is called.
Contd….
• Once a thread is inside a synchronized method, no other thread can call any other
synchronized method on the same object.
• This enables you to write very clear and concise multithreaded code, because
synchronization support is built into the language.

• Messaging : After you divide your program into separate threads, you need to
define how they will communicate with each other.
• When programming with most other languages, you must depend on the operating
system to establish communication between threads. This, of course, adds overhead.
• By contrast, Java provides a clean, low-cost way for two or more threads to talk to
each other, via calls to predefined methods that all objects have.
• Java’s messaging system allows a thread to enter a synchronized method on an object,
and then wait there until some other thread explicitly notifies it to come out.
The Thread Class and the Runnable Interface

• Java’s multithreading system is built upon the Thread class, its methods, and its
companion interface, Runnable.
• Thread encapsulates a thread of execution.
• Since you can’t directly refer to the ethereal state of a running thread, you will deal
with it through its proxy, the Thread instance that spawned it.
• To create a new thread, your program will either extend Thread or implement the
Runnable interface.
• The Thread class defines several methods that help manage threads.
The Main Thread
• When a Java program starts up, one thread begins running immediately.
• This is usually called the main thread of your program, because it is the one that is
executed when your program begins.
• The main thread is important for two reasons:
• It is the thread from which other “child” threads will be spawned.
• Often, it must be the last thread to finish execution because it performs various
shutdown actions.
• Although the main thread is created automatically when your program is started, it can
be controlled through a Thread object.
• To do so, you must obtain a reference to it by calling the method currentThread( ),
which is a public static member of Thread.
• Its general form is shown here:
static Thread currentThread( )
• This method returns a reference to the thread in which it is called. Once you have a
reference to the main thread, you can control it just like any other thread.
Example
// Controlling the main Thread.
class CurrentThreadDemo
{
public static void main(String args[ ]) {
Thread t = Thread.currentThread( );
System.out.println("Current thread: " + t);
// change the name of the thread In this program, a reference to
t.setName("My Thread"); the current thread (the main
System.out.println("After name change: " + t); thread, in this case) is
try { obtained by calling
for(int n = 5; n > 0; n--) currentThread( ), and this
{ reference is stored in the local
System.out.println(n); variable t.
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted");
}
}
}
Contd….
• In this program, a reference to the current thread (the main thread, in this case) is
obtained by calling currentThread( ), and this reference is stored in the local
variable t.
• The program then calls setName( ) to change the internal name of the thread.
Information about the thread is then redisplayed.
• Next, a loop counts down from five, pausing one second between each line. The pause
is accomplished by the sleep( ) method.
• The argument to sleep( ) specifies the delay period in milliseconds. Notice the
try/catch block around this loop.
• The sleep( ) method in Thread might throw an InterruptedException.
• This would happen if some other thread wanted to interrupt this sleeping one. This
example just prints a message if it gets interrupted.
• In a real program, you would need to handle this differently. Here is the output
generated by this program:

Current thread: Thread[main,5,main]


After name change: Thread[My Thread,5,main]
5 4 3 2 1
Contd…
• Notice the output produced when t is used as an argument to println( ). This
displays, in order: the name of the Its priority, and the name of its group.
• By default, the name of the main thread is main. Its priority is 5, which is the
default value, and main is also the name of the group of threads to which this thread
belongs.
• A thread group is a data structure that controls the state of a collection of threads as a
whole.
• After the name of the thread is changed, t is again output. This time, the new name
of the thread is displayed.
• Let’s look more closely at the methods defined by Thread that are used in the
program. The sleep( ) method causes the thread from which it is called to suspend
execution for the specified period of milliseconds.

static void sleep(long milliseconds) throws InterruptedException


• The number of milliseconds to suspend is specified in milliseconds. This method may
throw an InterruptedException.
• The sleep( ) method has a second form, shown next, which allows you to specify
the period in terms of milliseconds and nanoseconds:
Contd…
• General Form

static void sleep(long milliseconds, int nanoseconds) throws InterruptedException


• This second form is useful only in environments that allow timing periods as short as
nanoseconds.
• As the preceding program shows, you can set the name of a thread by using setName(
).
• You can obtain the name of a thread by calling getName( )
• These methods are members of the Thread class and are declared like this:
final void setName(String threadName)
final String getName( )
Creating a Thread
• In the most general sense, you create a thread by instantiating an object of type
Thread.
• Java defines two ways in which this can be accomplished:
• You can implement the Runnable interface.
• You can extend the Thread class, itself.

1) Implementing Runnable : The easiest way to create a thread is to create a class


that implements the Runnable interface.
• Runnable abstracts a unit of executable code.
• You can construct a thread on any object that implements Runnable.
• To implement Runnable, a class need only implement a single method called run(),
which is declared like this:
public void run( )
Inside run( ), you will define the code that constitutes the new thread.
• It is important to understand that run( ) can call other methods, use other classes,
and declare variables, just like the main thread can.
Contd….
• The only difference is that run( ) establishes the entry point for another, concurrent
thread of execution within your program. This thread will end when run( ) returns.
• After you create a class that implements Runnable, you will instantiate an object of
type Thread from within that class.
• Thread defines several constructors. The one that we will use is shown here:
Thread(Runnable threadOb, String threadName)

• In this constructor, threadOb is an instance of a class that implements the Runnable


interface. This defines where execution of the thread will begin. The name of the new
thread is specified by threadName.

• After the new thread is created, it will not start running until you call its start( )
method, which is declared within Thread.

• In essence, start( ) executes a call to run( ). The start( ) method is shown here:
void start( )
Programs
// Create a second thread.
class NewThread implements Runnable
{
Thread t; class ThreadDemo
NewThread( ) {
{
public static void main(String args[])
// Create a new, second thread
t = new Thread(this, "Demo Thread"); {
System.out.println("Child thread: " + t); new NewThread( ); // create a new thread
t.start(); // Start the thread try {
} for(int i = 5; i > 0; i--) {
// This is the entry point for the second thread. System.out.println("Main Thread: " + i);
public void run( ) Thread.sleep(1000);
{
}
try {
for(int i = 5; i > 0; i--) } catch (InterruptedException e)
{ {System.out.println("Main thread
System.out.println("Child Thread: " + i); interrupted.");
Thread.sleep(500); }
} System.out.println("Main thread exiting.");
} catch (InterruptedException e) { }
System.out.println("Child interrupted.");
}
}
System.out.println("Exiting child thread.");
}
}
Contd…
• Inside NewThread’s constructor, a new Thread object is created by the following
statement:
t = new Thread(this, "Demo Thread");
• Passing this as the first argument indicates that you want the new thread to call
the run( ) method on this object.
• Next, start( ) is called, which starts the thread of execution beginning at the
run( ) method.
• This causes the child thread’s for loop to begin. After calling start( ), NewThread’s
constructor returns to main( ).
• When the main thread resumes, it enters its for loop. Both threads continue running,
sharing the CPU, until their loops finish.
• In fact, for some older JVMs, if the main thread finishes before a child thread has
completed, then the Java run-time system may “hang.”
• The preceding program ensures that the main thread finishes last, because the main
thread sleeps for 1,000 milliseconds between iterations, but the child thread sleeps for
only 500 milliseconds.
• This causes the child thread to terminate earlier than the main thread.
Contd…
• 2) Extending Thread: The second way to create a thread is to create a new class
that extends Thread, and then to create an instance of that class.
• The extending class must override the run( ) method, which is the entry point for the
new thread.
• It must also call start( ) to begin execution of the new thread. Here is the preceding
program rewritten to extend Thread:

PROGRAM
• This program generates the same output as the preceding version. As you can see, the
child thread is created by instantiating an object of NewThread, which is derived
from Thread.
• Notice the call to super( ) inside NewThread. This invokes the following form of
the Thread constructor:
public Thread(String threadName)
• Here, threadName specifies the name of the thread.
Choosing an Approach
• At this point, you might be wondering why Java has two ways to create child threads,
and which approach is better.
• The answers to these questions turn on the same point. The Thread class defines
several methods that can be overridden by a derived class.
• Of these methods, the only one that must be overridden is run( ).
• This is, of course, the same method required when you implement Runnable.
• Many Java programmers feel that classes should be extended only when they are
being enhanced or modified in some way.
• So, if you will not be overriding any of Thread’s other methods, it is probably best
simply to implement Runnable.
Creating Multiple Threads
• So far, you have been using only two threads: the main thread and one child thread.
However, your program can spawn as many threads as it needs.
// Create multiple threads.
class NewThread implements Runnable
{
String name; // name of thread
Thread t;
class MultiThreadDemo
NewThread(String threadname) { {
name = threadname; public static void main(String args[ ]) {
t = new Thread(this, name); new NewThread("One"); // start threads
System.out.println("New thread: " + t); new NewThread("Two");
t.start(); // Start the thread new NewThread("Three");
} try {
// This is the entry point for thread.
public void run( ) {
// wait for other threads to end
Try { Thread.sleep(10000);
for(int i = 5; i > 0; i--) { } catch (InterruptedException e) {
System.out.println(name + ": " + i); System.out.println("Main thread Interrupted");
Thread.sleep(1000); }
} System.out.println("Main thread exiting.");
} catch (InterruptedException e) { }
System.out.println(name + "Interrupted");
}
}
System.out.println(name + " exiting.");
}
}
Using isAlive( ) and join( )
• As mentioned, often you will want the main thread to finish last. In the preceding
examples, this is accomplished by calling sleep( ) within main( ), with a long
enough delay to ensure that all child threads terminate prior to the main thread.
• However, this is hardly a satisfactory solution, and it also raises a larger question:
• How can one thread know when another thread has ended?
• Two ways exist to determine whether a thread has finished.
• First, you can call isAlive( ) on the thread.
• Second, more commonly use to wait for a thread to finish is called join( ).
True
General form of isAlive( ) : final boolean isAlive( )
False

The isAlive( ) method returns true if the thread upon which it is called is still
running.
• Returns false otherwise.
Contd…
• While isAlive( ) is occasionally useful.
join()------------→ final void join( ) throws InterruptedException

This method waits until the thread on which it is called terminates.


• Its name comes from the concept of the calling thread waiting until the specified
thread joins it.
• Additional forms of join( ) allow you to specify a maximum amount of time that
you want to wait for the specified thread to terminate.
• Here is an improved version of the preceding example that uses join( ) to ensure that
the main thread is the last to stop.

PROGRAM
As you can see, after the calls to join( ) return, the threads have stopped executing.
Thread Priorities
• Thread priorities are used by the thread scheduler to decide when each thread should
be allowed to run.
• Higher-priority threads get more CPU time than lower-priority threads.
• A higher-priority thread can also preempt a lower-priority one.
• For instance, when a lower-priority thread is running and a higher-priority thread
resumes, it will preempt the lower priority thread.
• To set a thread’s priority, use the setPriority( ) method, which is a member of Thread.
final void setPriority(int level)
Level: MIN_PRIORITY (1)
NORM_PRIORITY (5) (Default)
MAX_PRIORITY (10)
You can obtain the current priority setting by calling the getPriority( ) method of
Thread.
final int getPriority( )
• In theory, threads of equal priority should get equal access to the CPU. But you need
to be careful.
Contd…
• Remember, Java is designed to work in a wide range of environments. Some of
those environments implement multitasking fundamentally differently than others.
• For safety, threads that share the same priority should yield control once in a while.
• This ensures that all threads have a chance to run under a non-preemptive operating
system.
• In practice, even in non-preemptive environments, most threads still get a chance to
run, because most threads inevitably encounter some blocking situation, such as
waiting for I/O.
• When this happens, the blocked thread is suspended and other threads can run. But,
if you want smooth multithreaded execution, you are better off not relying on this.
• Also, some types of tasks are CPU-intensive. Such threads dominate the CPU. For
these types of threads, you want to yield control occasionally so that other threads
can run.
• Implementations of Java may have radically different behavior when it comes to
scheduling.
• Most of the inconsistencies arise when you have threads that are relying on
preemptive behavior, instead of cooperatively giving up CPU time.
Contd….
• The safest way to obtain predictable, cross-platform behavior with Java is to use
threads that voluntarily give up control of the CPU.
• The following example demonstrates two threads at different priorities, which do not
run on a preemptive platform in the same way as they run on a nonpreemptive
platform.
• One thread is set two levels above the normal priority, as defined by
Thread.NORM_PRIORITY, and the other is set to two levels below it.
• The threads are started and allowed to run for ten seconds. Each thread executes a
loop, counting the number of iterations. After ten seconds, the main thread stops both
threads.
•PROGRAM
One other note about the preceding program. Notice that running is
preceded by the keyword volatile.
while (running) {
click++;
}
• Without the use of volatile, Java is free to optimize the loop in such a way that a
local copy of running is created.
Synchronization
• When two or more threads need access to a shared resource, they need some way to
ensure that the resource will be used by only one thread at a time.
• The process by which this is achieved is called synchronization. As you will see, Java
provides unique, language-level support for it.
• Key to synchronization is the concept of the monitor (also called a semaphore). A
monitor is an object that is used as a mutually exclusive lock, or mutex.
• Only one thread can own a monitor at a given time. When a thread acquires a lock, it
is said to have entered the monitor.
• All other threads attempting to enter the locked monitor will be suspended until the
first thread exits the monitor.
• These other threads are said to be waiting for the monitor. A thread that owns a
monitor can reenter the same monitor if it so desires.
• If you have worked with synchronization when using other languages, such as C or
C++, you know that it can be a bit tricky to use.
• This is because these languages do not, themselves support synchronization.
• Because other languages need operating system primitives for synchronization, But in
java synchronization doesn’t need operating system primitives.
Contd…
• Java implements synchronization through language elements, most of the complexity
associated with synchronization has been eliminated.
• You can synchronize your code in either of two ways. Both involve the use of the
synchronized keyword.
• Using Synchronized Methods: Synchronization is easy in Java, because
all objects have their own implicit monitor associated with them.
• To enter an object’s monitor, just call a method that has been modified with the
synchronized keyword
• While a thread is inside a synchronized method, all other threads that try to call it (or
any other synchronized method) on the same instance have to wait.
• To exit the monitor and relinquish control of the object to the next waiting thread, the
owner of the monitor simply returns from the synchronized method.
EXAMPLE
• The following program has three simple classes. The first one, Callme, has a single
method named call( ). The call( ) method takes a String parameter called msg. This
method tries to print the msg string inside of square brackets. The interesting thing
to notice is that after call( ) prints the opening bracket and the msg string, it calls
Thread .sleep(1000), which pauses the current thread for one second.
Contd…
• The constructor of the next class, Caller, takes a reference to an instance of the
Callme class and a String, which are stored in target and msg, respectively.
• The constructor also creates a new thread that will call this object’s run( ) method.
The thread is started immediately. The run( ) method of Caller calls the call( )
method on the target instance of Callme, passing in the msg string.
• As you can see, by calling sleep( ), the call( ) method allows execution to switch to
another thread.
• This results in the mixed-up output of the three message strings.
• In this program, nothing exists to stop all three threads from calling the same method,
on the same object, at the same time.
• This is known as a race condition, because the three threads are racing each other to
complete the method. This example used sleep( ) to make the effects repeatable and
obvious.
• In most situations, a race condition is more subtle and less predictable, because you
can’t be sure when the context switch will occur. This can cause a program to run
right one time and wrong the next.
• To fix the preceding program, you must serialize access to call( ).
Example
class Callme
{
synchronized void call(String msg)
{
...

synchronized has been added to call( ), the output of the program is as follows:
• [Hello]
• [Synchronized]
• [World]
• Any time that you have a method, or group of methods, that manipulates the internal
state of an object in a multithreaded situation, you should use the synchronized
keyword to guard the state from race conditions.

• The synchronized Statement : While creating synchronized methods within


classes that you create is an easy and effective means of achieving synchronization,
it will not work in all cases.
Contd….
• To understand why, consider the following.
• Imagine that you want to synchronize access to objects of a class that was not
designed for multithreaded access.
• That is, the class does not use synchronized methods. Further, this class was not
created by you, but by a third party, and you do not have access to the source code.
• Thus, you can’t add synchronized to the appropriate methods within the class.
• This is the general form of the synchronized statement:
synchronized(object)
{
// statements to be synchronized
}
• Here, object is a reference to the object being synchronized. A synchronized block
ensures that a call to a method that is a member of object occurs only after the current
thread has successfully entered object’s monitor.
Interthread communication
• multithreading replaces event loop programming by dividing your tasks into discrete,
logical units.
• Threads also provide a secondary benefit: they do away with polling.
• Polling is usually implemented by a loop that is used to check some condition
repeatedly. Once the condition is true, appropriate action is taken. This wastes CPU
time.

• For example, consider the classic queuing problem, where one thread is producing
some data and another is consuming it.

• suppose that the producer has to wait until the consumer is finished before it generates
more data. In a polling system, the consumer would waste many CPU cycles while it
waited for the producer to produce.

• Once the producer was finished, it would start polling, wasting more CPU cycles waiting
for the consumer to finish, and so on.
• Clearly, this situation is undesirable.
Contd….

• To avoid polling, Java includes interprocess communication mechanism via


the
wait( ), notify( ), and notifyAll( ) methods.

• These methods are implemented as final methods in Object, so all classes have
them.
• All three methods can be called only from within a synchronized context.
• wait( ) tells the calling thread to give up the monitor and go to sleep until some
other thread enters the same monitor and calls notify( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of
the threads will be granted access.
• These methods are declared within Object, as shown here:
• final void wait( ) throws InterruptedException
• final void notify( )
• final void notifyAll( )
Producer-Consumer Problem
Contd…
Producer-Consumer Program
Contd…
Example
Contd…
Deadlock
Deadlock

• Deadlock describes a situation where two or more threads are blocked forever, waiting for
each other.
• Deadlocks can occur in Java when the synchronized keyword causes the executing thread to
block while waiting to get the lock, associated with the specified object.
• Since the thread might already hold locks associated with other objects, two threads
could each be waiting for the other to release a lock. In such case, they will end up
waiting forever.
Suspending, resuming and stopping threads
• Prior to Java 2, a program used suspend( ) and resume( ), which are methods defined
by
• Thread, to pause and restart the execution of a thread.
• They have the form shown below:
• final void suspend( )
• final void resume( )
• The Thread class also defines a method called stop( ) that stops a thread
• final void stop( )
• Once a thread has been stopped, it cannot be restarted using resume( ).
Contd…
Events are s u p p o r t e d b y a n u m b e r o f
packages, including java.util, java.awt, a n d
java.awt.event.

There are several t y p e s of events, including


t h o s e generated b y t h e m o u s e , t h e keyboard,
a n d various GUI controls, s u c h as a p u s h
b u t t o n , scroll bar, or c h e c k b o x .
T h e Delegation Event Model

T h e m o d e r n approach t o handling e v e n t s is
b a s e d o n t h e delegation event model, which
defines standard and consistent m e c h a n i s m s
t o generate and process events.
Its c o n c e pt is quite simple:
a source generates an e v e n t and s e n d s it t o
o n e or m o re listeners
In this s c h e m e , t h e listener simply waits until
it receives an event. Once an e v e n t is
received, t h e listener p ro ce sses t h e e v e n t and
t h e n returns.
Even t s
In t h e delegation m o d e l , an event is an object
that describes a state change in a source. It
can b e generated as a c o n s e q u e n c e o f a
p e r s o n interacting with t h e e l e m e n t s in a
graphical user interface.

S o m e o f t h e activities that cause e v e n t s t o b e


generated are pressing a b u t t o n , entering a
character via t h e keyboard, selecting an i t e m
in a list, a n d clicking t h e m o u s e .
Event Sources
A source is an object that generates an event.
This occurs w h e n t h e internal state of that
object changes in s o m e way. Sources m a y
generate m o re than o n e t y p e o f event .

A source m u s t register listeners in order for


t h e listeners t o receive notifications a b o ut a
specific t y p e o f event. Each t y p e o f e v e n t has
its o w n registration m e t h o d .

Here is t h e general form:


public void add Type Listener( Type Listener el)
Here, Type is t h e n a m e o f t h e event, a n d el is
a reference t o t h e e v e n t listener.
For e x a m p l e , t h e m e t h o d that registers a
keyboard e v e n t listener is called
addKeyListener( ).

When an e v e n t occurs, all registered listeners


are notified and receive a copy o f t h e e v e n t
object.
Event Listeners

A listener is an object that is notified w h e n an


e v e n t occurs. It has t w o major requirements.

First, it m u s t have b e e n registered with o n e


or m o re sources t o receive notifications a bout
specific t y p e s o f events.

Second, it m u s t i m p l e m e n t m e t h o d s t o
receive a n d process t h e s e notifications.
Event Classes

Java defines several t y p e s o f e v e n t s .

Th e m o s t widely u s e d e v e n t s are t h o s e
defined b y t h e AWT.
At t h e root o f t h e Java e v e n t class hierarchy is
EventObject, which is in java.util.
It is t h e superclass for all events. Its o n e
constructor is s h o w n here:
EventObject(Object src )

Here, src is t h e object that generates this


event.
Th e class AWTEvent, defined within t h e
java.awt package, is a subclass o f
EventObject.
It is t h e superclass o f all AW T- b a s e d e v e n t s
u s e d b y t h e delegation e v ent m o d e l .

To s u mma r i z e :
EventObject is a superclass o f all events.
AWTEvent is a superclass o f all AWT e v e n t s
that are handled b y t h e delegation e v ent
model.
Th e package java.awt.event defines m a n y
t y p e s o f e v e n t s that are generated b y various
user interface e l e m e n t s
Th e AdjustmentEvent Class

An AdjustmentEvent is generated b y a scroll


bar. There are five t y p e s o f a d j u s t m e n t
events.
T h e AdjustmentEvent class defines integer
constants that can b e u s e d t o identify t h e m .
Th e constants a n d their m e a n i n g s are s h o w n
here:
Th e ComponentEvent Class

A ComponentEvent is generated w h e n t h e
size, position, or visibility o f a c o m p o n e n t is
changed.
There are four t y p e s o f c o m p o n e n t events.

Th e ComponentEvent class defines integer


constants that can b e u s e d t o identify t h e m .
T h e ContainerEvent Class

AContainerEvent is generated w h e n a c o m p o n e n t is
a d d e d t o or re m o v e d f ro m a container.
There are t w o t y p e s o f container events. T h e
ContainerEvent class defines int constants that can b e
u s e d t o identify t h e m : COMPONENT_ADDED and
COMPONENT_REMOVED.

They indicate that a c o m p o n e n t has b e e n a d d e d t o or


re m o v e d f ro m t h e container.
ContainerEvent is a subclass of ComponentEvent and
has this constructor:

ContainerEvent(Component src , int type , C o m p o n e n t


comp )
.
Here, src is a reference t o t h e container that
generated this event.

T h e t y p e o f t h e e v e n t is specified b y type,
a n d t h e c o m p o n e n t that has b e e n a d d e d t o or
re m o v e d f ro m t h e container is comp
Th e FocusEvent Class

AFocusEvent is generated w h e n a c o m p o n e n t
gains or loses input focus.

T h e s e e v e n t s are identified b y t h e integer


constants FOCUS_GAINED a n d FOCUS_LOST.

FocusEvent is a subclass o f ComponentEvent


a n d has t h e s e constructors:

FocusEvent(Component src , int type )


FocusEvent(Component src , int type , boolean
temporaryFlag )
FocusEvent(Component src , int type , boolean
temporaryFlag , C o m p o n e n t other )

Here, src is a reference t o t h e c o m p o n e n t that


generated this event. T h e t y p e o f t h e e v e n t is
specified b y type.

T h e a rg u m e n t temporaryFlag is s e t t o true if
t h e f o cus e v ent is temporary. Otherwise, it is
s e t t o false.
T h e ItemEvent Class

An ItemEvent is generated w h e n a c h e c k b o x
or a list i t e m is clicked or w h e n a checkable
m e n u i t e m is selected or deselected.

There are t w o t y p e s o f i t e m events, which are


identified b y t h e following integer constants:
In addition, ItemEvent defines o n e integer
constant, ITEM_STATE_CHANGED, that
signifies a change o f state.
ItemEvent has this constructor:
ItemEvent(ItemSelectable src , int type , Object
entry , int state )
Here, src is a reference t o t h e c o m p o n e n t that
generated this e v e n t
For e x a m p l e , this m i g h t b e a list or choice
e l e me n t .

T h e t y p e o f t h e e v e n t is specified b y type.

Th e specific i t e m that generated t h e i t e m


e v e n t is p a s s e d in entry. T h e current state of
that i t e m is in state.
T h e KeyEvent Class

A KeyEvent is generated w h e n keyboard input


occurs. There are three t y p e s o f k e y events,
which are identified b y t h e s e integer
constants:
KEY_PRESSED, KEY_RELEASED, and
KEY_TYPED.
T h e first t w o e v e n t s are generated w h e n any
k e y is p re s s e d or released.
T h e last e v e n t occurs only w h e n a character is
generated.
There are m a n y other integer constants that
are defined b y KeyEvent.
For e x a m p l e , VK_0 t h rough VK_9 a n d VK_A
t h rough VK_Z define t h e ASCII equivalents o f
t h e n u m b e r s and letters.
Th e MouseEvent Class

There are eight t y p e s o f m o u s e even ts. T h e


MouseEvent class defines t h e following
integer constants that can b e u s e d t o identify
t h e m:
MouseEvent is a subclass o f InputEvent. Here is o n e
of its constructors:
MouseEvent(Component src , int type , long
when , int modifiers , int x , int y , int
clicks , boolean triggersPopup )

Here, src is a reference t o t h e c o m p o n e n t that


gener ated t h e event.
T h e t y p e o f t h e e v e n t is specified b y type.
T h e s y s t e m t i m e at which t h e m o u s e e v e n t occurred
is p a s s e d in when.
T h e modifiers a rg u m e n t indicates which modifiers
were p re s s e d w h e n a m o u s e e v e n t occurred.
T h e coordinates of t h e m o u s e are p a s s e d in x and y.
T h e click c o u n t is p a s s e d in clicks.
T h e triggersPopup flag indicates if this e v e n t causes a
p o p - u p m e n u t o appear o n this platform.
Th e TextEvent Class

T h e s e are generated b y t e x t fields a n d t e x t


areas w h e n characters are entered b y a user
or program. TextEvent defines t h e integer
constant TEXT_VALUE_CHANGED.
T h e o n e constructor for this class is s h o w n
here:
TextEvent(Object src , int type )
Here, src is a reference t o t h e object that
generated this event.
Th e t y p e o f t h e e v e n t is specified b y type.
Th e WindowEvent Class

There are t e n t y p e s o f window events.


TheWindowEvent class defines integer
constants that can b e u s e d t o identify t h e m .
T h e c o n s tants and their m e a n i n g s are s h o w n
here:
WindowEvent is a subclass o f
ComponentEvent. It defines several
constructors.
T h e first is WindowEvent(Window src , int type )
Here, src is a reference t o t h e object that
generated this event. T h e t y p e o f t h e e v e n t is
type .
T h e delegation e v e n t m o d e l has t w o parts:
sources a n d listeners.
Listeners are created b y i mp l e me n t i n g o n e or
m o re o f t h e interfaces defined b y t h e
java.awt.event package.
When an e v e n t occurs, t h e e v e n t source
invokes t h e appropriate m e t h o d d ef i n ed b y
t h e listener an d provides an e v e n t object as
its a rgume nt.
T h e ActionListener Interface

This interface defines t h e actionPerformed( )


m e t h o d that is invoked w h e n an action event
occurs.
Its general f o r m is s h o w n here:

void actionPerformed(ActionEvent ae )
Th e AdjustmentListener Interface.

This interface defines t h e


adjustmentValueChanged( ) m e t h o d that is
invoked w h e n an a d j u s t m e n t e v e n t occurs. Its
general f o r m is s h o w n here:

void
adjustmentValueChanged(AdjustmentEvent
ae )
Th e ComponentListener Interface

This interface defines four m e t h o d s that are


invoked w h e n a c o m p o n e n t is resized,
m o v e d , s h o w n , or hidden.

Their general f o r m s are s h o w n here:

void c o mp o nentRe sized(C o mpone ntEve nt ce )


void componentMoved(ComponentEvent ce )
void c o mp o nentShow n(C o mponentEv ent ce )
void componentHidden(ComponentEvent ce )
T h e ContainerListener Interface

This interface contains t w o m e t h o d s . When a


c o m p o n e n t is a d d e d t o a container,
c o m p o n e n t A d d e d ( ) is invoked.
When a c o m p o n e n t is re m o v e d f ro m a
container, c o m p o n e n t R e m o v e d ( ) is invoked.

Their general f o r m s are s h o w n here:

void componentAdded(ContainerEvent ce )
void componentRemoved(ContainerEvent ce )
Java provides a special feature, called an
adapter class, that can simplify t h e creation
o f e v e n t handlers in certain situations.
An adapter class provides an e m p t y
implementation o f all m e t h o d s in an
eve nt listener interface.
Adapter classes are useful w h e n yo u want to
receive and process only s o m e o f t h e eve nt s
that are handled by a particular eve nt listener
interface.
You can define a n e w class t o act as an event
listener by e x t e n d i n g o n e of t h e adapter classes
and i mp l emen t i n g only t h o s e event s in which you
are interested.

For e x a m p l e , t h e MouseMotionAdapter class has


t w o m e t h o d s , mouseDragged( ) and
mous eMo ve d ( ), which are t h e m e t h o d s defined
by t h e MouseMotionListener interface.

If you were interested in only m o u s e drag events,


t h e n yo u could simply e x t e n d
MouseMotionAdapter and override
mouseDra gg ed( ).

T he e m p t y implement at i on of mouseMoved( )
would handle t h e m o u s e m o t i o n event s for you.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code="AdapterDemo" w i d t h = 3 0 0
height=100>
</applet>
*/
public class AdapterDemo e x t e n d s Applet {
public void init() {
addMouseListener(new MyMouseAdapter(this));
addMouseMotionListener(new
MyMouseMotionAdapter(this));
}
}
class MyMouseAdapter e x t e n d s MouseAdapter
{
Adapter D em o adapterDemo;
public MyMouseAdapter(AdapterDemo adapterDemo) {
this.adapterDemo = adapterDemo;
}

/ / Handle m o u s e clicked.
public void mouseClicked(MouseEvent m e )
{
adapterDemo.showStatus("Mouse clicked");
}
}
class MyMouseMotionAdapter e x t e n d s
MouseMotionAdapter {
Adapter D em o adapterDemo;
public MyMouseMotionAdapter(AdapterDemo
adapterDemo) {
this.adapterDemo = adapterDemo;
}
/ / Handle m o u s e dragged.

public void mouseDragged(MouseEvent m e )


{
adapterDemo.showStatus("Mouse dragged");
}
}
Inner Classes

an inner class is a class defined within


another class, or e v e n within an exp ressio n .
/ / This applet d o e s NOT u s e an inner class.
import java.applet.*;
import java.awt.event.*;
/*
<applet code="MousePressedDemo" w i d t h = 2 0 0 h e i g h t = 1 0 0 >
</applet>
*/
public class MousePressedDemo e x t e n d s Applet {
public void init() {
addMouseListener(new MyMouseAdapter(this));
}
}
class MyMouseAdapter e x t e n d s MouseAdapter {
MousePressedDemo mousePressedDemo;
public MyMouseAdapter(MousePressedDemo mousePressedDemo) {
this.mouseP ressedDem o = mousePressedDemo;
}
public void mousePressed(MouseEvent m e) {
mousePressedDemo.showStatus("Mouse Pressed.");
}
}
/ / Inner class d e m o .
import java.applet.*;
import java.awt.event.*;
/*
<applet code="InnerClassDemo" w i d t h = 2 0 0
height=100>
</applet>
*/
public class InnerClassDemo e x t e n d s Applet {
public void init() {
addMouseListener(new MyMouseAdapter());
}
class MyMouseAdapter e x t e n d s MouseAdapter {
public void mousePressed(MouseEvent m e ) {
showStatus("Mouse Pressed");
}
}
}
In Java’s original GUI subsystem: the Abstract
Window Toolkit. T he AWT defines a basic s e t
of controls, windows, and dialog b o x e s that
s u p p o r t a usable, b u t limited graphical interface.

One reason for t h e limited nature of t h e AWT is


that it translates its various visual c o m p o n e n t s
into their corresponding, platform-specific
equivalents, or peers .

This m e a n s that t h e look and feel of a


c o m p o n e n t is defined b y t h e platform, n o t b y
Java. Because t h e AWT c o m p o n e n t s
u s e native c o d e resources, t hey are referred t o as
heavyweight
Swing is a s e t of classes that provides m o re
powerful and flexible GUI c o m p o n e n t s than
d o e s t h e AWT.

Although Swing eliminates a n u m b e r of t h e


limitations inherent in t h e AWT, Swing does
not replace it.

Instead, Swing is built o n t h e foundation o f t h e


AWT. This is w h y t h e AWT is still a crucial part
o f Java.

Swing also u s e s t h e s a m e e v e n t handling


m e c h a n i s m as t h e AWT.
Swing C o m p o n e n t s Are Lightweight

With very f e w exceptions, Swing c o m p o n e n t s are


lightweight . This m e a n s that t h e y are written entirely in
Java a nd d o n o t m a p directly t o platform-specific peers.

Because lightweight c o m p o n e n t s are rendered using


graphics primitives, t h e y can b e transparent. T h u s,
lightweight c o m p o n e n t s are m o re efficient a n d m o re
flexible.

Furthermore, b e c a use lightweight c o m p o n e n t s d o n o t


translate into native peers, t h e look a n d feel o f each
c o m p o n e n t is d e t e r m i n e d b y Swing, n o t b y t h e underlying
operating s y s t e m .

This m e a n s that each c o m p o n e n t will work in a consistent


ma n n e r across all platforms.
Swing Supports a Pluggable Look a n d Feel

Swing s u p p o r t s a pluggable look and feel


(PLAF). Because each Swing c o m p o n e n t is
rendered b y Java c o d e rather than b y native
peers, t h e look and feel o f a c o m p o n e n t is
u n d er t h e control o f Swing.

This fact m e a n s that it is possible t o separate


t h e look and feel o f a c o m p o n e n t f ro m t h e
logic o f t h e c o m p o n e n t , and this is what
Swing d o e s .
Pluggable l o o k - a n d - f e e l s offer several important
advantages. It is possible t o define a look and
feel that is consistent across all platforms.

T h e MVC Connection (Model-View-Container)

In general, a visual c o m p o n e n t is a c o m p o s i t e of
three distinct aspects:
• T he way that t h e c o m p o n e n t looks w h e n
rendered o n t h e screen
• T h e way that t h e c o m p o n e n t reacts t o t h e user
• T h e state information associated with
the component
Th e MVC architecture is successful b e cause
each piece o f t h e d esign corresponds t o an
aspect o f a c o m p o n e n t .

In MVC terminology, t h e model corresponds


t o t h e state information associated with t h e
component.

For e x a m p l e , in t h e case o f a c h e c k b o x , t h e
m o d e l contains a field that indicates if t h e
b o x is c h e c k e d or u n c h e c k e d .

T h e view d e t e r mi n e s h o w t h e c o m p o n e n t is
displayed o n t h e screen, including any
aspects o f t h e view that are affected b y t h e
current state of t h e m o d e l .
Th e controller d e t e r mi n e s h o w t h e
c o m p o n e n t reacts t o t h e user.

For e x a m p l e , w h e n t h e user clicks a c h e c k


b o x , t h e controller reacts b y changing t h e
m o d e l to reflect the user’s choice (checked or
unchecked).

This t h e n results in t h e view being u p d a t e d .


By separating a c o m p o n e n t into a m o d e l , a
view, and a controller, t h e specific
implementation o f each can b e c h a n g e d
without affecting t h e other two.
A Swing GUI consists of t w o k e y items:
components
• distinction o s t l y containers
is m and co n c e pt u a l .bHowever,
e c a u s e all this
containers are also c o m p o n e n t s .

T h e d iffe re n c e b e t w e e n t h e t w o is f o u n d in their
i n t e n d e d p u r p o se : A s t h e t e r m is c o m m o n l y u s e d , a
component is a n i n d e p e n d e n t visual control, s u c h a s
a p u s h b u t t o n or slider.

A container h o l d s a g r o u p o f c o m p o n e n t s . T h u s , a
container is a special t y p e o f c o m p o n e n t t h at is
designed to hold other component s .
Components

In general, Swing c o m p o n e n t s are derived f ro m


t h e JComponent class.

JComponent provides t h e functionality that is


c o m m o n t o all c o m p o n e n t s .

For e x a m p l e , JComponent inherits t h e AWT


classes Container and C o m p o n e n t .

Thus, a Swing c o m p o n e n t is built o n and


compatible with an AWT c o m p o n e n t .

All of Swing’s components are represented by


classes defined within t h e package javax.swing.
T h e following table s h o w s t h e class n a m e s for
Swing c o m p o n e n t s
Containers

Swing defines t w o t y p e s o f containers. T h e


first are t o p-level containers: JFrame, JApplet,
JWindow, and JDialog.

T h e s e containers d o n o t inherit JComponent.


They d o , however, inherit t h e AWT classes
C o m p o n e n t an Container.

T h e s e c o n d t y p e of containers s u p p o r t e d b y
Swing are lightweight containers. Lightweight
containers do inherit JComponent
S w i n g - b a s e d applets are similar t o AW T-
b a s e d applets, b u t with an important
difference: A Swing applet e x t e n d s JApplet
rather than Applet.

JApplet is derived f ro m Applet. Thus, JApplet


includes all o f t h e functionality f o u n d in
Applet a n d a d d s s u p p o r t for Swing
Swing applets u s e t h e s a m e four lifecycle
m e t h o d s : init( ), start( ), stop( ), a n d destroy().

Of course, y o u n e e d t o override only t h o s e


m e t h o d s that are n e e d e d b y your applet.

Here is an e x a m p l e o f a Swing applet.


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
This HTML can b e u s e d t o launch t h e applet:
<applet code="MySwingApplet" w i d t h = 2 2 0
height=90>
</applet>
*/
public class MySwingApplet e x t e n d s JApplet {
JButton jbtnAlpha;
JButton jbtnBeta;
JLabel jlab;
/ / Initialize t h e applet.
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable () {
public void run() {
makeGUI(); / / initialize t h e GUI
}
});
}
catch(Exception exc) {
System.out.println("Can't create because of "+ exc);
}
}
/ / This applet d o e s n o t n e e d t o override start(), stop(),
/ / or destroy().
/ / Set u p and initialize t h e GUI.
private void makeGUI() {
/ / Set t h e applet t o u s e flow layout.

setLayout(new FlowLayout());

/ / Make t w o b u t t o n s .
jbtnAlpha = n e w JButton("Alpha");
jbtnBeta = n e w JButton("Beta");

/ / A d d action listener for Alpha.


jbtnAlpha.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent le) {
jlab.setText("Alpha was pressed.");
}
});

/ / A d d action listener for Beta.


jbtnBeta.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent le) {
jlab.setText("Beta was pressed.");
}
});
/ / A d d t h e b u t t o n s t o t h e c o n t e n t pane.

add(jbtnAlpha);
add(jbtnBeta);

/ / Create a t e x t - b a s e d label.

jlab = n e w JLabel("Press a button.");


/ / A d d t h e label t o t h e c o n t e n t pane.
add(jlab);
}
}
T h e Swing c o m p o n e n t classes described are
s h o w n here:

T h e s e c o m p o n e n t s are all lightweight, which


m e a n s that t h e y are all derived f ro m
JComponent.
JLabel a n d ImageIcon

JLabel is Swing’s easiest-to-use c o m p o n e n t .


Here, w e will look at JLabel a bit m o re closely.

JLabel can b e u s e d t o display t e x t a n d / o r an icon.


It is a passive c o m p o n e n t in that it d o e s n o t
re s p o n d t o user input.

JLabel defines several constructors. Here are


three o f t h em :

JLabel(Icon icon )
JLabel(String str )
JLabel(String str , Icon icon , int align )
Here, str and icon are t h e t e x t and icon u s e d
for t h e label.

Th e align arg u me n t specifies t h e horizontal


alignment of t h e t e x t a n d / o r icon within t h e
d i m e n s i o n s o f t h e label.

It m u s t b e o n e of t h e following values: LEFT,


RIGHT, CENTER, LEADING, or TRAILING.
/ / Demonstrate JLabel and ImageIcon.

import java.awt.*;
import javax.swing.*;
/*
<applet code="JLabelDemo" w i d t h = 2 5 0
height=150>
</applet>
*/
public class JLabelDemo e x t e n d s JApplet {
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable()
{
public void run() {
makeGUI();
}
}
);

} catch (Exception exc) {


System.out.println("Can't create becau se of "
+exc);
}
}
private void makeGUI() {
/ / Create an icon.
ImageIcon ii = n e w ImageIcon("france.gif");
/ / Create a label.
JLabel jl = n e w JLabel("France", ii, JLabel.CENTER);
/ / A d d t h e label t o t h e cont ent pane.
add(jl);
}
}
Ou t p u t f ro m t h e label e x a m p l e is s h o w n here:
JTextField is t h e s i m p l e s t Swing t e x t c o m p o n e n t . It is
also probably its m o s t widely u s e d t e x t c o m p o n e n t .
JTextField allows y o u t o edit o n e line of t e x t .

It is derived f ro m JTextComponent, which provides


t h e basic functionality c o m m o n t o Swing t e x t
components.

JTextField u s e s t h e D o c u m e n t interface for its m o d e l .

Three o f JTextField’s constructors are s h o w n here:

JTextField(int cols )
JTextField(String str , int cols )
JTextField(String str )
Here, str is t h e string t o b e initially pres ented ,
and cols is t h e n u m b e r of c o l u m n s in t h e t e x t
field.

If n o string is specified, t h e t e x t field is


initially e m p t y. If t h e n u m b e r o f c o l u m n s is
n o t specified, t h e t e x t field is s i z e d t o fit t h e
specified string.
Swing defines four t y p e s o f buttons:
JButton, JToggleButton, JCheckBox, and
JRadioButton.
T he JButton class provides t h e functionality o f a
push button.

JButton allows an icon, a string, or b o t h t o b e


associated with t h e p u s h b u t t o n .

Three o f its constructors are s h o w n here:

JButton(Icon icon )
JButton(String str )
JButton(String str , Icon icon )
Here, str an d icon are t h e string and icon u s e d
for t h e b u t t o n . When t h e b u t t o n is pressed, an
ActionEvent is generated .
A useful variation o n t h e p u s h b u t t o n is called a
toggle button .

A toggle b u t t o n looks just like a p u s h b u t t o n ,


b u t it acts differently becaus e it has t w o states:
p u s h e d and released.

That is, w h e n you press a toggle b u t t o n , it stays


p re s s e d rather than p o p p i n g back u p as a regular
push button does.

When yo u press t h e toggle b u t t o n a s e c o n d time,


it releases (pops up). Therefore, each t i m e a
toggle b u t t o n is p u s h e d , it toggles b e t w e e n its
t w o states.
T h e JCheckBox class provides t h e
functionality o f a c h e c k b o x . Its i m m e d i a t e
superclass is JToggleButton, which provides
s u p p o r t for t w o - s t a t e b u t t o n s .

JCheckBox defines several constructors. T h e


o n e u s e d here is
JCheckBox(String str )

It creates a c h e c k b o x that has t h e t e x t


specified b y str as a label
Radio b u t t o n s are a group o f mutually
exclusive b u t t o n s , in which only o n e b u t t o n
can b e selected at any o n e time.

They are s u p p o r t e d b y t h e JRadioButton class,


which e x t e n d s JToggleButton.

JRadioButton provides several constructors.


T h e o n e u s e d in t h e e x a m p l e is s h o w n here:

JRadioButton(String str )

Here, str is t h e label for t h e b u t t o n .


In Swing, t h e basic list class is called JList. It
s u p p o r t s t h e selection of o n e or m o re i t e m s
f ro m a list.

Although t h e list o f t e n consists o f strings, it


is possible t o create a list o f just a b o ut any
object that can b e displayed.

JList is s o widely u s e d in Java that it is highly


unlikely that y o u have n o t s e e n o n e before.
JList provides several constructors. T h e o n e
u s e d here is

JList(Object[ ] items )

This creates a JList that contains t h e i t e m s in


t h e array specified b y items .
Swing provides a combo b o x (a combination of a t e x t
field and a d ro p - d o w n list) through t h e JComboBox
class.

A c o m b o b o x normally displays o n e entry, b u t it will


also display a d ro p - d o w n list that allows a user t o
select a different entry. You can also create a c o m b o
b o x that lets t h e user enter a selection into t h e t e x t
field.

T h e JComboBox constructor u s e d b y t h e e x a m p l e is
s h o w n here:

JComboBox(Object[ ] items )

Here, items is an array that initializes t h e c o m b o b o x .


A tree is a c o m p o n e n t that p re s e n t s a
hierarchical view o f data. T h e user h a s t h e
ability t o e x p a n d or collapse individual
s u b t re e s in this display.

Trees are i m p l e m e n t e d in Swing by t h e JTree


class. A sampling of its constructors is s h o w n
here:

JTree(Object obj [ ])
JTree(Vector<?> v)
JTree(TreeNode tn )
JTable is a c o m p o n e n t that displays rows and
c o l u m n s o f data. You can drag t h e cursor o n
c o l u m n boundaries t o resize c o l u mn s . You
can also drag a c o l u m n t o a n e w position.

JTable has m a n y classes and interfaces


associated with it. T h e s e are packaged in
javax.swing.table.
JTable d o e s n o t provide any scrolling
capabilities o f its own. Instead, y o u will
normally wrap a Jtable inside a JScrollPane.

JTable supplies several constructors. T h e o n e


u s e d here is

JTable(Object data [ ][ ], Object colHeads [ ])

Here, data is a t w o - d i me n s io nal array o f t h e


information t o b e p re se nted, and colHeads is
a o n e - d i me n s i o n a l array with t h e c o l u m n
headings.
Here are t h e s t e p s required t o s e t u p a simple
JTable that can b e u s e d t o display data:

1. Create an instance o f JTable.


2. Create a JScrollPane object, specifying t h e
table as t h e object t o scroll.
3. A d d t h e table t o t h e scroll pane.
4. A d d t h e scroll p a ne t o t h e c o n t e n t pane.

You might also like