Module - 2 - Oop With Java
Module - 2 - Oop With Java
Lecture notes
Scheme 2022
MODULE II
Introducing Classes: Class Fundamentals, Declaring Objects, Assigning Object Reference Variables, Introducing
Methods, Constructors, This Keyword, Garbage Collection.
Methods and Classes: Overloading Methods, Objects as Parameters, Argument Passing, Returning Objects, Recursion,
Access Control, understanding static, introducing final, Introducing Nested and Inner Classes.
Bike
boolean kickstart
boolean buttonstart
int gears
accelerate()
applyBrak e()
changeGear()
Example of class:
Create a class structure that may represent the details of Employee .
An employee has several characteristics that you can represent as variables such as name, salary,
etc.
Write a method details () which consists of println() statements that print the values of instance
variables. The Employee class can be defined as follows:
class Employee
{
String name; / / Instance Variables
int salary; / / Instance Variables
➢ CREATING OBJECTS:
Example:
Employee sam=new Employee();
This statement combines the two steps just described. It can be rewritten like this to show each step more clearly:
Employee sam; // declare reference to object
sam=new Employee(); / / allocate a Employee object
• After this line executes, sam contains the value null, which indicates that it does not yet point to an actual
object.
• Any attempt to use sam at this point will result in a compile -time error. The next line allocates an
actual object and assigns a reference to it to sam.
Statement Effect
Employee
salary
• The new operator dynamically allocates memory for an object. The general form is:
class-var = new classname ( );
• The classname is the name of the class that is being instantiated. The class name followed by
parentheses specifies the constructor for the class.
• A constructor defines what occurs when an object of a class is created.
• Most real-world classes explicitly define their own constructors within their class definition. However,
if no explicit constructor is specified, then Java will automatically supply a default constructor.
• In example, JVM will initialize the instance variables using a default constructor.
• Java’s primitive types are not implemented as objects and so new operator is not required for
them.
• new allocates memory for an object during run time , so can create as many or as few objects as
needed during the execution .
Assigning Object Reference Variables:
Employee s1=new Employee();
Employee s2=s1;
s1
name
salary
s2
Employee
A subsequent assignment to s1 will simply unhook s1 from the original object without affecting the
object or affecting s2.
For example:
Employee s1=new Employee();
Employee s2=s1;
// ...
s1 = null;
Here, s1 has been set to null, but s2 still points to the original object.
➢ METHODS:
• type specifies the type of data returned by the method. This can be any valid type, including class
types that we create.
• If the method does not return a value, its return type must be void .
• The name of the method is specified by name. This can be any legal identifier other than those
already used by other items within the current scope.
• The parameter -list is a sequence of type and identifier pairs separated by commas.
• If the method has no parameters, then the parameter list will be empty.
• Methods that have a return type other than void , return a value to the calling routine using the
following form of the return statement:
return value ;
Here, value is the value returned.
➢ CONSTRUCTORS:
Whenever an object is created for a class, the instance variables of the class need to be given initial
values.
Java allows objects to initialize themselves when they are created. This automatic initialization is
performed using a constructor.
A constructor is a special method which initializes an object immediately upon creation. It has the same
name as the class in which it resides and is syntactically like a method.
When a constructor is not defined for a class, Java compiler provides a default constructor
which automatically initializes all instance variables to their default values.
The constructor is automatically invoked as soon as the object is instantiated with the new keyword.
Constructors have no return type, not even void. This is because the implicit return type of a class’
constructor is the class type itself.
If any constructor is defined in the class then the JVM will not provide any constructor.
Example, a simple constructor that simply sets the dimensions of each Box to the same values.
/* Here, Box uses a constructor to initialize the dimensions of a box.
class Box
{
double width;
double height;
double depth;
Box( )
width = 10;
height = 10;
depth = 10;
}
double volume( )
{
// compute and return volume
Parameterized Constructors:
The Box( ) constructor in the preceding example initializes all boxes with the same dimensions.
Parameters can be passed to a constructor, like having parameters for a method. This makes them
much more useful.
Example:
// Here, Box uses a parameterized constructor to initialize the dimensions of a box. class Box
{
double width;
double height;
double depth;
Box(double w, double h, double d)//This is the constructor for Box
{
width = w;
height = h;
depth = d;
}
double volume( )
{
// compute and return volume return
width * height * depth;
}
}
class BoxDemo
{
public static void main(String args[ ])
{
// declare, allocate, and initialize Box objects Box
mybox1 = new Box(10, 20, 15);
double vol;
vol = [Link](); //// get volume of first box
[Link]("Volume is " + vol);
vol = [Link](); // get volume of second box
[Link]("Volume is " + vol);
}
}
The output from this program is shown here:
Volume is 3000.0
Volume is 162.0
Each object is initialized with values specified in the parameters to its constructor. For example, in
the following line,
Box mybox1 = new Box(10, 20, 15);
The values 10, 20, and 15 are passed to the Box( ) constructor when new creates the object. Thus,
mybox1’s copy of width, height, and depth will contain the values 10, 20, and 15 respectively.
➢ ‘this’ KEYWORD :
• Java defines the ‘this ’ keyword. this can be used inside any instance method to refer to the current
object.
• this is always a reference to the object on which the method was invoked.
• Example:
Example:
// Automatic type conversions apply to overloading.
class OverloadDemo
{
void test()
{
[Link]("No parameters");
}
void test(int a, int b)
{
// Overload test for two integer parameters.
int i = 88;
[Link]();//no parameter
[Link](10, 20);// 10 20
[Link](i); 88
[Link](123.2); 123.2
}}
a and b: 10 20
OVERLOADING CONSTRUCTORS:
• Constructors for a class having the same name as that of class, but with different signatures I.e., different number
of arguments or different types of arguments.
Example:
class Box
{
double width;
double height;
double depth;
Box(double w, double h, double d)
{
//constructor used when all dimensions specified
width = w;
height = h;
depth = d;
}
Box()
{
// constructor used when no dimensions specified
}
class OverloadCons
{
public static void main(String args[])
{
// create boxes using the various constructors
Output:
Volume of mybox1 is 3000.0 Volume
of mybox2 is -1.0.
Volume of mycube is 343.0
ACCESS CONTROL :
Encapsulation provides another important attribute: access control. Through encapsulation, we can control what parts of a
program , can access the members of a class.
The access modifiers in Java specifies accessibility (scope) of a data member, method, constructor, or class.
private int c;
void setc(int i)
{
c = i;
}
int getc()
{
return c;
}
}
class AccessTest
{
public static void main(String args[])
{
Test ob = new Test();
ob.a = 10;
ob.b = 20;
ob.c = 100;
[Link](100);
[Link]("a, b, and c: " + ob.a + " " + ob.b + " " + [Link]());
}
}
1. Private Access Modifier: The private access modifier is accessible only within class. Example:
class A
{
private int data=40;
private void msg( )
{
[Link]("Hello java");
}
}
public class Simple
{
public static void main(String args[])
{
A obj=new A();
[Link]([Link]);
[Link]();
}
}
Example:
In this example, we have created the two packages pack and mypack. The A class of pack package is public, so can be accessed
from outside the package. But msg method of this package is declared as protected, so it can be accessed from outside the class only
through inheritance.
//save by [Link]
package pack;
public class A
{
protected void msg( )
{
[Link]("Hello");
}
}
//save by [Link]
package mypack;
import pack.*;
class B extends A
{
public static void main(String args[])
{
B obj = new B();
[Link]();
}
}
Output:
Hello
Access Modifier Within Class Within Package Outside Package Outside Package
By Subclass Only
Private Y N N N
Protected Y Y Y N
Public Y Y Y Y
Overloading Methods
Having more than one method with a same name is called as method overloading. To implement this concept, the
constraints are:
the number of arguments should be different, and/or
Type of the arguments must be different.
NOTE that, only the return type of the method is not sufficient for overloading.
class Overload
{
void test( ) //method without any arguments
{
[Link]("No parameters");
}
void test(int a) //method with one integer argument
{
[Link]("Integer a: " + a);
}
void test(int a, int b) //two arguments
{
[Link]("With two arguments : " + a + " " + b);
}
void test(double a) //one argument of double type
{
[Link]("double a: " + a);
}
}
class OverloadDemo
{
public static void main(String args[])
{
Overload ob = new Overload();
[Link]();
[Link](10);
[Link](10, 20);
[Link](123.25);
}
}
Overloading Constructors
One can have more than one constructor for a single class if the number and/or type of arguments are different.
Consider the following code:
class OverloadConstruct
{
int a, b;
OverloadConstruct()
{
[Link]("Constructor without arguments");
}
OverloadConstruct(int x)
{
a=x;
[Link]("Constructor with one argument:"+a);
}
OverloadConstruct(int x, int y)
{
a=x;
b=y;
[Link]("Constructor with two arguments:"+ a +"\t"+ b);
}
}
class OverloadConstructDemo
{
public static void main(String args[])
{
OverloadConstruct ob1= new OverloadConstruct();
OverloadConstruct ob2= new OverloadConstruct(10);
OverloadConstruct ob3= new OverloadConstruct(5,12);
}
}
Output:
Constructor without arguments
Constructor with one argument: 10
Constructor with two arguments: 5 12
Just similar to primitive types, even object of a class can also be passed as a parameter to any method. Consider the
example given below –
class Test
{
int a, b;
Test(int i, int j)
{
a = i;
b = j;
}
boolean equals(Test ob)ob1:100 22 ob2:100 22 ob1: 100 22 ob3: -1 -1
{
if(ob.a == this.a && ob.b == this.b)
100==100 && 22==22
return true;
else
return false;
}
}
class PassOb
{
public static void main(String args[])
{
Test ob1 = new Test(100, 22);
Test ob2 = new Test(100, 22);
Test ob3 = new Test(-1, -1);
[Link]("ob1 == ob2: " + [Link](ob2));
[Link]("ob1 == ob3: " + [Link](ob3));
}
}
Output:
ob1 == ob2: true
ob1 == ob3: false
Returning Objects
class Test {
int a;
Test(int i)
{
a = i;
Test incrByTen()
{
Test temp = new Test(a+10);
return temp;
class RetOb {
Output:
ob1.a: 2
ob2.a: 12
ob2.a after second increase: 22
• Call by value : This approach copies the value of an argument into the formal parameter of the method.
Therefore, changes made to the parameter of the method have no effect on the argument.
Inside the subroutine, this reference is used to access the actual argument specified in the call. This means
that changes made to the parameter will affect the argument used to call the subroutine.
In Java, when you pass a primitive type to a method, it is passed by value. When you pass an object
to a method, they are passed by reference. Keep in mind that when you create a variable of a class type,
you are only creating a reference to an object. Thus, when you pass this reference to a method, the parameter
that receives it will refer to the same object as that referred to by the argument. This effectively means that
objects are passed to methods by use of call-by- reference. Changes to the object inside the method do
affect the object used as an argument.
class Test
int a, b;
Test(int i, int j)
{
a = i;
b = j;
void meth(Test o)
{
o.a *= 2;
o.b /= 2;
Output:
before call: 15 20
after call: 30 10
Recursion
A method which invokes itself either directly or indirectly is called as recursive method. Every recursive method should satisfy
following constraints:
class Factorial
{
int fact(int n)
{
if (n==0)
return 1;
return n*fact(n-1);
}
}
class FactDemo
{
public static void main(String args[])
{
Factorial f= new Factorial();
[Link]("Factorial 3 is "+ [Link](3));
[Link]("Factorial 8 is "+ [Link](8));
Output:
Factorial of 3 is 6
Factorial of 8 is 40320
Understanding static
When a member is declared static, it can be accessed before any objects of its class are created, and without
reference to any object. Instance variables declared as static are global variables. When objects of its class are
declared, no copy of a static variable is made. Instead, all instances of the class share the same static variable.
class StaticDemo
{
static int a = 42;
static int b = 99;
static void callme()
{
[Link]("Inside static method, a = " + a);
} }
class StaticByName
{
public static void main(String args[])
{
[Link]();
[Link]("Inside main, b = " + StaticDemo.b);
} }
Output:
Inside static method, a = 42
Inside main, b = 99
USING FINAL
import [Link].*;
class A
{
public int i;
final int SPEED_LIMIT=60;
public A()
{
[Link](" \n \t default constructor A() is called");
i=10;
}
public final void Aadd() // not overrided since final
{
[Link](" \n \t in A class final add() method is called ");
i=i+10;
}
public void Adisplay()
{
[Link](" \n \t in A class i= "+i);
}
}
class B extends A
{
public int j;
public B()
{
[Link] tln("\n \t default constructor B() is called");
j=20;
}
public void Badd()
j=j+i;
}
public void Bdisplay()
{
[Link](" \n \t in B class j= "+j);
}
}
class FinalMethod
{
public static void main(String ar[]) throws IOException
{
[Link](" \n \t start of main()");
B b=new B();
[Link]();
[Link]();
[Link]();
[Link]();
[Link](" \n \t end of main()");
}
} OUTPUT
start of main()
default constructor A() is called
in A class i=20
in B class Badd() is called
in B class j=40
end of main()
public A()
{
[Link](" \n \t default constructor A() is called");
i=10;
}
public final void Aadd() // not overrided since final
{
[Link](" \n \t in A class final add() method is called ");
i=i+10;
}
public void Adisplay()
{
[Link]("\n \t in A class i= "+i);
}
}
class FinalCV
{
public static void main(String ar[]) throws IOException
{
[Link](" \n \t start of main()");
OUT PUT :
start of main()
in main() the value of final f=100
It is possible to define a class within another class; such classes are known as nested classes. The scope of a
nested class is bounded by the scope of its enclosing class. Thus, if class B is defined within class A, then
B does not exist independently of A. A nested class has access to the members, including private members,
of the class in which it is nested. However, the enclosing class does not have access to the members of the
nested class.
There are two types of nested classes: static and non-static. A static nested class is one that has the static
modifier applied. Because it is static, it must access the members of its enclosing class through an object.
That is, it cannot refer to members of its enclosing class directly. Because of this restriction, static nested
classes are seldom used. The most important type of nested class is the inner class.
An inner class is a non-static nested class. It has access to all the variables and methods of its outer class
and may refer to them directly in the same way that other non-static members of the outer class do.
Example:
class Outer
{
int outer_x = 100;
void test()
{
Inner inner = new Inner();
[Link]();
}
// this is an inner class
class Inner
class InnerClassDemo
{
public static void main(String args[])
{
Outer outer = new Outer();
[Link]();
}
}
Output:
display:
outer_x = 100