0% found this document useful (0 votes)
12 views38 pages

Java Class Fundamentals and Examples

The document introduces object-oriented programming concepts, focusing on class fundamentals, methods, constructors, and access control in Java. It includes examples of C and Java programs demonstrating the calculation of sums and volumes using classes and methods. Additionally, it covers constructors, the 'this' keyword, and method overloading, highlighting the advantages of object-oriented design.

Uploaded by

manojtalawar009
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views38 pages

Java Class Fundamentals and Examples

The document introduces object-oriented programming concepts, focusing on class fundamentals, methods, constructors, and access control in Java. It includes examples of C and Java programs demonstrating the calculation of sums and volumes using classes and methods. Additionally, it covers constructors, the 'this' keyword, and method overloading, highlighting the advantages of object-oriented design.

Uploaded by

manojtalawar009
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Module 2

Introducing Classes: Class Fundamentals, Declaring Objects, Assigning Object


Reference Variables, Introducing Methods, Constructors, The 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.

Laboratory Experiment list : Q3, Q4 and Q5

Why object oriented programming?

//Program in C language to find sum of two numbers

#include<stdio.h>

int main()
{
int sum(int,int);
int x,y;
printf("Enter two numbers");
scanf("%d %d",&x,&y);
printf("\nThe sum of the nos is %d\n",sum(x,y));
}

int sum(int a, int b)


{
return (a+b);
}

o/p
Enter two numbers4 6
The sum of the nos is 10

Access Control,

Here's a simple Java program that reads two numbers from the keyboard, calculates their
sum, and prints the result. This program uses classes and objects in java to achieve this.
package first;

Access Control

import [Link];

// Define a class to hold the logic for summing two numbers


class SumCalculator {
// Method to calculate the sum of two numbers
public int sum(int a, int b) {
return a + b;
}
}

public class Sum2 {


public static void main(String[] args) {
// Create a Scanner object to read input from the keyboard
Scanner sc = new Scanner([Link]);

// Prompt the user to enter the first number


[Link]("Enter the first number: ");
int num1 = [Link]();

// Prompt the user to enter the second number


[Link]("Enter the second number: ");
int num2 = [Link]();

// Create an object of SumCalculator class


SumCalculator calc = new SumCalculator();

// Calculate the sum of the two numbers


int result = [Link](num1, num2);

// Print the result


[Link]("The sum of " + num1 + " and " + num2 + " is: " + result);
}
}

o/p
Enter the first number: 4
Enter the second number: 5
The sum of 4 and 5 is: 9

Summary:
 C: Focuses on procedural programming, with direct manipulation of functions and
memory, offering direct control but requiring careful management of resources. It
implements procedural oriented paradigm and offers less important for the data
(safey) which are passed into a function.
 Java: Emphasizes object-oriented principles, abstraction, and safety, with automated
memory management and a robust standard library. It implements object oriented
paradigm and offers more important for the data (safey) which are passed into a
function which is in a class.
A class is declared by use of the class keyword. The skeletal structure of class is as follows

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. In most classes, the instance variables are acted upon and
accessed by the methods defined for that class. Thus, as a general rule, it is the methods that
determine how a class’ data can be used.
All methods have the same general form as main( ), which we have been using thus
far. However, most methods will not be specified as static or public. Notice that the general
form of a class does not specify a main( ) method. Java classes do not need to have a main(
)method. You only specify one if that class is the starting point for your program. Further,
some kinds of Java applications don’t require a main( ) method at all.

A Simple Class and declaring objects of it

/* A program that uses the Box class.

Call this file [Link]


*/
class Box {
double width;
double height;
double depth;
}

// This class declares an object of type Box.


class BoxDemo {

public static void main(String[] args) {


Box mybox = new Box();
double vol;

// assign values to mybox's instance variables


[Link] = 10;
[Link] = 20;
[Link] = 15;

// compute volume of box


vol = [Link] * [Link] * [Link];

[Link]("Volume is " + vol);


}
}

As just explained, when you create a class, you are creating a new data type. You can
use this type to declare objects of that type. However, obtaining objects of aclass is a two-
step process. First, you must declare a variable of the class type. This variable does not
define an object. Instead, it is simply a variable that can refer to an object. Second, you must
acquire an actual, physical copy of the object and assign it to that variable. You can do this
using the new operator. The new operator dynamically allocates (that is, allocates at run time)
memory for an object and returns a reference to it. This reference is, essentially, the
address in memory of the object allocated by new. This reference is then stored in the
variable. Thus, in Java, all class objects must be dynamically allocated. Let’s look at the
details of this procedure.
In the preceding sample programs, a line similar to the following is used to declare an object
of type Box:

This statement combines the two steps just described. It can be rewritten like this to
show each step more clearly

The effect of these two lines of code is depicted in the following figure
4

Assigning Object Reference Variables


Object reference variables act differently than you might expect when an assignment takes
place. For example, what do you think the following fragment does?

Introducing Methods

As mentioned at the beginning of this chapter, classes usually consist of two things:
instance variables and methods. The topic of methods is a large one because Java gives
them so much power and flexibility. In fact, much of the next chapter is devoted to methods.
However, there are some fundamentals that you need to learn now so that you can begin to
add methods to your classes. This is the general form of a method:

Here, type specifies the type of data returned by the method. This can be any valid
type, including class types that you 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. Parameters are essentially variables that receive the value of the arguments passed
to the method when it is called. 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;

Adding a Method to the Box Class

// This program includes a method inside the box class.

class Box {
double width;
double height;
double depth;

// display volume of a box


void volume() {
[Link]("Volume is “+ width* height * depth);
}
}

class BoxDemo3 {
public static void main(String[] args) {
Box mybox1 = new Box();
Box mybox2 = new Box();

// assign values to mybox1's instance variables


[Link] = 10;
[Link] = 20;
[Link] = 15;

/* assign different values to mybox2's


instance variables */
[Link] = 3;
[Link] = 6;
[Link] = 9;

// display volume of first box


[Link]();

// display volume of second box


[Link]();
}
}
o/p
Volume is 3000.0
Volume is 162.0

Returning a Value

While the implementation of volume( ) does move the computation of a box’s volume inside
the Box class where it belongs, it is not the best way to do it. For example, what if another
part of your program wanted to know the volume of a box, but not display its value? A better
way to implement volume( ) is to have it compute the volume of the box and return the result
to the caller. The following example, an
improved version of the preceding program, does just that:

// Now, volume() returns the volume of a box.

class Box {
double width;
double height;
double depth;

// compute and return volume


double volume() {
return width * height * depth;
}
}

class BoxDemo4 {
public static void main(String[] args) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;

// assign values to mybox1's instance variables


[Link] = 10;
[Link] = 20;
[Link] = 15;

/* assign different values to mybox2's


instance variables */
[Link] = 3;
[Link] = 6;
[Link] = 9;

// get volume of first box


vol = [Link]();
[Link]("Volume is " + vol);

// get volume of second box


vol = [Link]();
[Link]("Volume is " + vol);
}
}

Setting a Method That Takes Parameters with void and return result using returning
value

// This program uses a parameterized method.

class Box1 {
double width;
double height;
double depth;

// compute and return volume


double volume() {
return width * height * depth;
}

// sets dimensions of box


void setDim(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
}

class BoxDemo5 {
public static void main(String[] args) {
Box1 mybox1 = new Box1();
Box1 mybox2 = new Box1();
double vol;

// initialize each box


[Link](10, 20, 15);
[Link](3, 6, 9);

// get volume of first box


vol = [Link]();
[Link]("Volume is " + vol);
// get volume of second box
vol = [Link]();
[Link]("Volume is " + vol);
}
}

Constructors

A constructor is a special member function defined in class which has the same name
of the class. It is used to initialize the data members in a class when an object of the
class is created in the main function. The constructor will be automatically invoked
when the object of the class is created.

It can be tedious to initialize all of the variables in a class each time an instance is created.
Even when you add convenience functions like setDim( ), it would be simpler and more
concise to have all of the setup done at the time the object is first created. Because the
requirement for initialization is so common, Java allows objects to initialize themselves when
they are created. This automatic initialization of variable is performed through the use
of a constructor.

A constructor initializes an object immediately upon creation. It has the same name as the
class in which it resides and is syntactically similar to a method. Once defined, the
constructor is automatically called when the object is created, before the new operator
completes. Constructors look a little strange because they have no return type, not even void.
This is because the implicit return type of a class’ constructor is the class type itself.

Example program for non-parameterized constructor

package Second;
/* Here, Box uses a constructor to initialize the
dimensions of a box.
*/
class Box2 {
double width;
double height;
double depth;

// This is the constructor for Box.


Box2() {
[Link]("Constructing Box");
width = 10;
height = 10;
depth = 10;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}

class BoxDemo6 {
public static void main(String[] args) {
// declare, allocate, and initialize Box objects
Box2 mybox1 = new Box2(); //initialization of variables takes place by invoking constructor
Box2 mybox2 = new Box2();

double vol;

// get volume of first box


vol = [Link]();
[Link]("Volume is " + vol);

// get volume of second box


vol = [Link]();
[Link]("Volume is " + vol);
}
}

o/p
Constructing Box
Constructing Box
Volume is 1000.0
Volume is 1000.0

Parameterized Constructors

when a constructor is invoked automatically when the object is created, a set of data
values are passed as parameters from main method to the class. Such constructors with
parameters are used to store the data values onto the data members of the class.

Example program for parameterized constructor

package Second;

/* Here, Box uses a parameterized constructor to


initialize the dimensions of a box.
*/
class Box3 {
double width;
double height;
double depth;
// This is the constructor for Box.
Box3(double w, double h, double d) {
width = w;
height = h;
depth = d;
}

// compute and return volume


double volume() {
return width * height * depth;
}
}

class BoxDemo7 {
public static void main(String[] args) {
// declare, allocate, and initialize Box objects
Box3 mybox1 = new Box3(10, 20, 15);
Box3 mybox2 = new Box3(3, 6, 9);

double vol;

// get volume of first box


vol = [Link]();
[Link]("Volume is " + vol);

// get volume of second box


vol = [Link]();
[Link]("Volume is " + vol);
}
}

o/p
Volume is 3000.0
Volume is 162.0

The this Keyword

In oops, it is always desirable to use the same variable names both in the main method and in
the class defined. In this context , it will need to refer to the object that invoked it. To allow
this, Java defines the this keyword. this can be used inside any method to refer to the
current object. That is, this is always a reference to the object on which the method was
invoked. You can use this anywhere a reference to an object of the current class’ type is
permitted.

Example program

package Second;

/* Here, Box uses a parameterized constructor using this operator to


initialize the dimensions of a box.
*/
class Box4 {
double width;
double height;
double depth;

// This is the constructor for Box.


Box4(double width, double height, double depth) {
[Link] = width;
[Link] = height;
[Link] = depth;
}

// compute and return volume


double volume() {
return width * height * depth;
}
}

class BoxDemo8 {
public static void main(String[] args) {
// declare, allocate, and initialize Box objects
Box4 mybox1 = new Box4(10, 20, 15);
Box4 mybox2 = new Box4(3, 6, 9);

double vol;

// get volume of first box


vol = [Link]();
[Link]("Volume is " + vol);

// get volume of second box


vol = [Link]();
[Link]("Volume is " + vol);
}
}
o/p
Volume is 3000.0
Volume is 162.0

Method overloading

If a class has multiple methods having same name but different in parameters, it is known
as Method Overloading. The main advantage of using method overloading in Java is that it
saves time and effort to define a method again and again for performing the same task.
In the below example, the three methods are basically performing a division operation.
If we have to perform only one operation, having same name of the methods increases the
readability of the program. This makes the code more readable and easier to understand
and provides flexibility and convenience when working with different data types or
combinations of inputs.

Suppose , when you have to find the volumes of three shapes such as cube, cylinder and
rectangular box. Generally , we would create three separate methods such as volumecube() ,
volumecylinder(), volumerectangular(). But it is not clean code in oops. Creation of many such
methods with different names will result in confusion in future. To avoid the confusion , we
define 3 different methods with same name but different number of parameters and data
different data types . Look at the following example program for method overloading

package Second;

class Overload {

// method with one parameters


double volume(float l) {
return l * l * l;
}

// method witpublic class MyClass


{
//Overloaded method
public int multiply(int num1, num2)
h two parameters
double volume(float r, float h) {
return 3.1416 * r * r * h;
}

// method with three parameters


double volume(float l, float w, float h) {
return l * w * h;
}
}

public class MethodOverload {


public static void main(String args[]) {
Overload overload = new Overload();

// method with 1 parameter is invoked


double cube = [Link](5);
[Link]("Volume of cube is "+cube);

// method with 2 parameters is invoked


double cylinder = [Link](6, 12);

// result with 2 decimal points


[Link]("Volume of cylinder is %.2f", cylinder);
public class MyClass
{
//Overloaded method
public int multiply(int num1, num2)

// method with 3 parameters is invoked


double rectangleBox = [Link](5, 8, 9);

[Link]("\nVolume of ractangular box is "+ rectangleBox);


[Link]("");
}
}

o/p

Volume of cube is 125.0


Volume of cylinder is 1357.17
Volume of ractangular box is 360.0

Rules for Overloading in Java


Below are the rules that should be remembered in java overloading:

 The first and foremost rule of Method overloading is that Methods need to have the
same name with different number of parameters in a single class.

 Two or more methods in a class can undergo overloading based on distinct


signatures(different data types , number of parameters and sequence). The
signature encompasses the number of parameters, data types of parameters, and
the sequence of parameters ( if number of parameters is same , data types and
sequence of the parameters should be distinct)
 The return type of a method does not constitute a part of the signature. Attempting to
perform overloading based on the return type is not allowed, and the compiler
generates an error in such cases.

Rule 1: Methods need to have the same name with distinct number of parameters in a
single class.

Code Snippet to understand Rule 1:

public class MyClass


{
//Overloaded method
public int multiply(int num1, num2)
{
return num1 * num2;
}

//Overloading method
public int multiply(int num1, int num2, int num3) //method with different number of
parameters
{
return num1 * num2* num3;
}
}

Rule 2: A class can undergo overloading based on distinct signatures ( if number of


paramters is same , data types and sequence of the parameters should be distinct )

double add(double a , double b)


{
return (a + b);
}
double add(int a , double b)
{
return (a + b);
}

double add(double a, int b )


{
return (a + b);
}

Rule 3 :Attempting to perform overloading based on the return type is not allowed,
Code

Snippet to understand Rule 3:

Code Snippet to understand Rule 2:


public class MyClass
{
// Overloaded method
public int multiply(int num1, int num2)
{
return num1 * num2;
}

// Overloading method
public float multiply(int num1, int num2) //Not valid because we only chnaged the
return type
{
return num1 * num2;
}
}

Overloading Constructors

In addition to overloading normal methods, you can also overload constructor methods for
overloading constructors with different parameters. Sometimes there is a need of initializing
an object in different ways. This can be done using constructor overloading.

Example Program for Constructor Overloading

package Second;

//Java program to illustrate Constructor Overloading


class Box5 {
double width, height, depth;

// constructor used when all dimensions specified. This is constructor overloading


Box5(double width, double height, double depth)
{
[Link] = width;
[Link] = height;
[Link] = depth;
}

// constructor used when no dimensions specified


Box5()
{
[Link] = 0;
[Link] = 0;
[Link] = 0;
}
// constructor used when cube is created
Box5(double len)
{ width = height = depth = len; }

// compute and return volume


double volume()
{ return width * height * depth; }
}

//Driver code
public class ConstructorOverload {
public static void main(String args[])
{
// create boxes using the various
// constructors
Box5 mybox1 = new Box5(10, 20, 15); // constructor overloaded with 3 parameters is
invoked
Box5 mybox2 = new Box5(); // constructor with no dimenstions is invoked
Box5 mycube = new Box5(7); // constructor overloaded with one parameter is invoked

double vol;

// get volume of first box


vol = [Link]();
[Link]("Volume of mybox1 is " + vol);

// get volume of second box


vol = [Link]();
[Link]("Volume of mybox2 is " + vol);

// get volume of cube


vol = [Link]();
[Link]("Volume of mycube is " + vol);
}
}

o/p
Volume of mybox1 is 3000.0
Volume of mybox2 is 0.0
Volume of mycube is 343.0

Garbage Collection in Java

Garbage Collection is a process in Java that automatically deallocates memory by


identifying and removing objects that are no longer in use. This process helps in
managing memory efficiently, preventing memory leaks, and ensuring that the application
does not run out of memory.

In Java, memory management is handled by the Java Virtual Machine (JVM), and the
garbage collector is the component responsible for this. When an object is no longer
reachable or referenced by any part of the program, it becomes eligible for garbage collection.

Key Points:

Automatic Memory Management: Java developers do not need to manually free memory.
The garbage collector does this automatically.
Reachability: An object is eligible for garbage collection when it is no longer reachable by
any active part of the application.
Non-deterministic: The exact time when the garbage collector will run is not predictable, and
it is controlled by the JVM.

Example program for garbage collection


package Second;

public class GarbageCollectionExample {


// A class with a finalize method to demonstrate when an object is garbage collected
static class MyObject {
private int id;

public MyObject(int id) {


[Link] = id;
[Link]("Object " + id + " created.");
}
@Override
protected void finalize() throws Throwable {
// This method is called before the object is garbage collected
[Link]("Object " + id + " is being garbage collected.");
}
}
public static void main(String[] args) {
// Creating objects in a loop
for (int i = 1; i <= 5; i++) {
MyObject obj = new MyObject(i);
obj = null; // Dereferencing the object, making it eligible for garbage collection
}

// Suggesting JVM to run garbage collection


[Link]();

// Adding a delay to ensure garbage collection occurs before the program ends
try {
[Link](1000);
} catch (InterruptedException e) {
[Link]();
}

[Link]("End of main method.");


}
}

o/p

Object 1 created.
Object 2 created.
Object 3 created.
Object 4 created.
Object 5 created.
Object 5 is being garbage collected.
Object 4 is being garbage collected.
Object 3 is being garbage collected.
Object 2 is being garbage collected.
Object 1 is being garbage collected.
End of main method.
Methods of classes in Java

Method 1 : Subclass + Main_Calss Method

// Sub Class
class volume
{
private int side;

public volume(int side)


{
[Link]=side;
}
public void Display()
{
[Link]("The Volume of cube is "+side*side*side);
}
}
// Main Class
public class Main_Class1
{
public static void main(String [] args)
{
Volume v=new Volume(5);
[Link]();
}
}

o/p
The Volume of cube is 125

Method 2 :Main_Calss Method

// Main Class
public class Main_Class2
{
private int side;

public Main_Class2(int side)


{
[Link]=side;
}
public void Display()
{
[Link]("The Volume of cube is "+side*side*side);
}
public static void main(String [] args)
{
Main_Class2 m = new Main_Class2(5);
[Link]();
}
}

o/p

The Volume of cube is 125

Using Objects as Parameters

So far, we have only been using simple types as parameters to methods. However, it
is both correct and common to pass objects to methods. For example,

// Objects may be passed to methods.


class Test {
int a, b;

Test(int i, int j) {
a = i;
b = j;
}

// return true if o is equal to the invoking object


boolean equalTo(Test o) {
if (o.a == a && o.b == b) return true;
else return false;
}
}

class PassObject {
public static void main(String[] args) {
Test ob1 = new Test(100, 22);Access Control,
Test ob2 = new Test(100, 22);
Test ob3 = new Test(-1, -1);

[Link]("ob1 == ob2: " + [Link](ob2));

[Link]("ob1 == ob3: " + [Link](ob3));


}
}

o/p

ob1 == ob2: true


ob1 == ob3: false

Argument Passing

In general, there are two ways that a computer language can pass an argument to a
subroutine. The first way is call-by-value.
This approach copies the value of an argument into the formal parameter of the subroutine.
Therefore, changes made to the parameter of the subroutine have no effect on the argument.

The second way an argument can be passed is call-by-reference. In this approach, a


reference to an
argument (not the value of the argument) is passed to the parameter. 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.

Passing Arguments

Program for call-by-value

1. call-by-value. ( value of argument is passed)


2. call-by-reference. ( reference to an argument , not the value)

In general, there are two ways that a computer language can pass an argument to a
subroutine. The first way is call-by-value.
This approach copies the value of an argument into the formal parameter of the subroutine.
Therefore, changes made to the parameter of the subroutine have no effect on the argument.

The second way an argument can be passed is call-by-reference. In this approach, a


reference to an
argument (not the value of the argument) is passed to the parameter. Inside the subroutine,
this reference is usedAccess Control, 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.

Program for call-by-value


Program for call-by-value

package Basic;

//Simple Types are passed by value.


class Test2 {
private int a,b;
void meth(int a, int b) {
a *= 2;
b /= 2;
}
}

class CallbyValue {
public static void main(String[] args) {
Test2 ob = newAccess Control, Test2();
int a = 15, b = 20;

[Link]("a and b before call meth(): " +a + " " + b);

[Link](a, b);

[Link]("a and b after call meth() : "+a + " " + b);


}
}
o/p

a and b before call meth(): 15 20


a and b after call meth() : 15 20

Program for call-by-reference

// Call by reference Example program

package Basic;

class Test1 {
private int a, b;

Test1(int i, int j) {
a = i;
b = j;
}

// pass an object
void meth(Test1 o) {
o.a *= 2;
o.b /= 2;
a=o.a;
b=o.b;
}

public String toString()


{
return "a = "+a+" b= "+b;
}
}

class PassObjRef {
public static void main(String[] args) {
Test1 ob = new Test1(15, 20);

[Link]("Data members of ob before call meth() : ");


[Link](ob);
// passsing obj i.e reference of the object
[Link](ob);

[Link]("Data members of ob after call meth(): ");

[Link](ob);
}
}

o/p
Data members of ob before call meth() :
a = 15 b= 20
Data members of ob after call meth():
a = 30 b= 10

Program for returning object

package Second;

//Returning an object.
class Test3 {
int a;

Test3(int i) {
a = i;
}

Test3 incrByTen() {
Test3 temp = new Test3(a + 10);
return temp;
}
}

class RetObj {
public static void main(String[] args) {
Test3 ob1 = new Test3(2);
Test3 ob2;

ob2 = [Link]();
[Link]("ob1.a: " + ob1.a);
[Link]("ob2.a after first increase: "+ ob2.a);

ob2 = [Link]();
[Link]("ob2.a after second increase: "+ ob2.a);
}
}

o/p

ob1.a: 2
ob2.a after first increase: 12
ob2.a after second increase: 22

Understanding static

Static keyword in Java


There will be times when you will want to define a class member that will be used to
commonly share between different objects. Normally, a class member must be accessed only
in conjunction with an object of its class. However, it is possible to create a member that can
be used by itself, without reference to a specific instance.

The static keyword in java is used for memory management mainly. We can apply java static
keyword with variables and methods. The static keyword belongs to the class than instance of
the class.
The static can be:
1. variable (also known as class variable)
2. method (also known as class method)

1) Java static variable


If you declare any variable as static, it is known static variable.
• The static variable can be used to refer the common property of all objects (that is not
unique for each object) e.g. company name of employees,college name of students etc.
• The static variable gets memory only once in class area at the time of class loading.
​ Advantage of static variable
It makes your program memory efficient (i.e it saves memory).

To create such a member, precede its declaration with the keyword static. When a member is
declared static, it can be accessed before any objects of its class arecreated, and without
reference to any object.
You can declare both methods and
variables to be static. The most common example of a static member is main( ).
main( ) is declared as static because it must be called before any objects exist.
Instance variables declared as static are, essentially, 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.
Methods declared as static have several restrictions:
• They can only directly call other static methods of their class.
• They can only directly access static variables of their class.
• They cannot refer to this or super in any way.

Understanding problem without static variable

Class Student{
int rollno;
String name;
String college="";
}

Suppose there are 500 students in my college, now all instance data members will get
memory each time when object is [Link] student have its unique rollno and name so
instance data member is [Link], college refers to the common property of all [Link] we
make it static,this field will get memory only once.

Example of static variable

package Second;

//Example of static variable


class Student1
{
int rollno;
String name;
static String college ="ITS";

Student1(int r,String n){


rollno = r;
name = n;
}
void display (){
[Link](rollno+" "+name+" "+college);
}
}
class Static_Member {
public static void main(String args[]){
Student1 s1 = new Student1(111,"Karan");
Student1 s2 = new Student1(222,"Aryan");

[Link]();
[Link]();
}
}

o/p

111 Karan ITS


222 Aryan ITS

Program of counter by static variable

As we have mentioned above, static variable will get the memory only once, if any object
changes the value of the static variable, it will retain its value.

Example program

package Second;

//Program of counter by static variable


class Static_Counter
{
static int count=0;//will get memory only once and retain its value

Static_Counter()
{
count++;
[Link](count);
}

public static void main(String args[]){

Static_Counter c1=new Static_Counter();


Static_Counter c2=new Static_Counter();
Static_Counter c3=new Static_Counter();
}
}

Test it Now
Output:
1
2
3

Static methods

Program for explaining difference between static and non static methods

The nonstatic methods need to be invoked only by creating object from the class in which
they are defined whereas for the static methods([Link]()) , there is no need to
creat objects. Simply the static methods can be called just by class name.
([Link]())

below is the example program

class StaticTest {
private int x=10;
private static int y=5;
int l=2;
static int m=4;

// non-static method
int multiply(int a, int b){
return a * b;
}
void printnonstatic()
{
[Link]("non static value"+x);
}

static void printstatic()


{
[Link]("static value"+y);
}

// static method
static int add(int a, int b){
return a + b;
}
}

public class StaticNonStatic {

public static void main(String[] args) {

// create an instance of the StaticTest class


StaticTest st = new StaticTest();

// call the nonstatic method with instance


[Link](" 2 * 2 = " + [Link](2,2));

// call the static method without creating instance


[Link](" 2 + 3 = " + [Link](2,3));

[Link]();
[Link]();

// static variables from static method Math


[Link]([Link]);
[Link]([Link](25));

[Link]("Non static value l " + st.l);


[Link]("Static value m " + StaticTest.m);

}
o/p
2*2=4
2+3=5
non static value10
static value5
3.141592653589793
5.0
Non static value l 2
Static value m 4

Introducing Access Control (Access modifiers)Access Control,

There are two types of access modifiers in java:


Access modifiers and Non-access modifiers.
The access modifiers in java specifies accessibility (scope) of a data member, method,
constructor or class.
There are 4 types of java access modifiers:

1. private
2. default
3. protected
4. public

There are many non-access modifiers such as static, abstract, synchronized, native, volatile,
transient etc. Here, we will learn access modifiers.

1. Public : Class,Method,Field is accessible from anywhere.


2. Default: Method,Field,class can be accessed only from the same package and not from
outside of it’s native package.
3. Protected:Method,Field can be accessed from the same class to which they belong or
from the sub-classes,and from the class of same package,but not from outside.
4. Private: Method,Field can be accessed from the same class to which they belong.

​1) private access modifier


The private access modifier is accessible only within class.

Simple example of private access modifier

In this example, we have created two classes A and Simple. A class contains private data
member and private method. We are accessing these private members from outside the
class, so there is compile time error.

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]);//Compile Time Error
[Link]();//Compile Time Error
}
}

Role of Private Constructor: If you make any class constructor private, you cannot create
the instance of that class from outside the class. For example:

Class A{
private A(){}//private constructor
void msg(){[Link]("Hello java");}
}

public class Simple{


public static void main(String args[]){
A obj=new A();//Compile Time Error
}
}

2) default access modifier

If you don't use any modifier, it is treated as default bydefault. The default modifier is
accessible only within package.

Example of default access modifier

In this example, we have created two packages pack and mypack. We are accessing the A
class from outside its package, since A class is not public, so it cannot be accessed from
outside the package.

//save by name [Link]


package pack;
class A{
void msg(){[Link]("Hello");}
}

//save by [Link]

package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();//Compile Time Error
[Link]();//Compile Time Error
}
}

3) protected access modifier

The protected access modifier is accessible within package and outside the package but
through inheritance only. The protected access modifier can be applied on the data member,
method and constructor. It can't be applied on the class.

Example of protected access modifier


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

4) public access modifier

The public access modifier is accessible everywhere. It has the widest scope among all other
modifiers.
Example of public access modifier

//save by [Link]

package pack;
public class A{
public void msg(){[Link]("Hello");}
}
//save by [Link]

package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();
[Link]();
}
}
Output:Hello

Understanding all java access modifiers


Let's understand the access modifiers by a simple table.

outside outside
Access within within
package by packag
Modifier class package
subclass only e
Private Y N N N
Default Y Y N N
Protected Y Y Y N
Public Y Y Y Y

Introducing final

A field can be declared as final. Doing so prevents its contents from being modified,
making it, essentially, a constant. This means that you must initialize a final field
when it is declared.

Final Keyword In Java

The final keyword in java is used to restrict the user. The java final keyword can be used in
many context. Final can be:
1. variable
2. method
3. class

1) Java final variable

If you make any variable as final, you cannot change the value of final variable(It will be
constant).

Example of final variable


There is a final variable speedlimit, we are going to change the value of this variable, but It
can't be changed because final variable once assigned a value can never be changed.
Class Bike9{
final int speedlimit=90;//final variable
void run(){
speedlimit=400;
}
public static void main(String args[]){
Bike9 obj=newBike9();
[Link]();
}
}//end of class
Output:Compile Time Error

2) Java final method

If you make any method as final, you cannot override it.


Example of final method
Class Bike{
final void run(){[Link]("running");
}
}

class Honda extends Bike{


void run(){[Link]("running safely with 100kmph");// trying to override run method
//which already declared as
final
}

public static void main(String args[]){


Honda honda= new Honda();
[Link]();
}
}
Output:Compile Time Error

3) Java final class

If you make any class as final, you cannot extend it.

Example of final class


final class Bike{}

class Honda1 extends Bike{


void run(){[Link]("running safely with 100kmph");}

public static void main(String args[]){


Honda1 honda= new Honda();
[Link]();
}
}
Output:Compile Time Error

Introducing Nested and Inner Classes

Java Inner Classes (Nested Classes)

Java inner class or nested class is a class that is declared inside the class or interface.

We use inner classes to logically group classes and interfaces in one place to be more
readable and maintainable.
In Java, it is possible to define a class within another class, such classes are known as
nested classes. They enable you to logically group classes that are only used in one place,
thus this increases the use of encapsulation and creates more readable and maintainable
code.

Additionally, it can access all the members of the outer class, including private data members
and methods.

Syntax of Inner class

class Java_Outer_class{
//code
class Java_Inner_class{
//code
}
}
Advantage of Java inner classes

Nested classes represent a particular type of relationship that is it can access all the
members (data members and methods) of the outer class, including private.
Nested classes are used to develop more readable and maintainable code because it
logically group classes and interfaces in one place only.
Code Optimization: It requires less code to write.
Need of Java Inner class
Sometimes users need to program a class in such a way so that no other class can access it.
Therefore, it would be better if you include it within other classes.

If all the class objects are a part of the outer object then it is easier to nest that class inside
the outer class. That way all the outer class can access all the objects of the inner class.

1. Non-Static Nested Class (Inner Class)


A non-static nested class, also known as an inner class, is associated with an instance of the
outer class. It has access to the instance variables and methods of the outer class.

public class OuterClass {


private String outerField = "Outer class field";

// Non-static nested class (inner class)


public class InnerClass {
public void display() {
// Accessing outer class's field
[Link]("Accessing from Inner Class: " + outerField);
}
}

public static void main(String[] args) {


// Creating an instance of OuterClass
OuterClass outer = new OuterClass();

// Creating an instance of InnerClass using the OuterClass instance.( it is required here)


[Link] inner = [Link] InnerClass();

// Calling method of InnerClass


[Link]();
}
}
Output:

Accessing from Inner Class: Outer class field

2. Static Nested Class

A static nested class does not require an instance of the outer class. It cannot directly access
instance variables or methods of the outer class; it can only access static members.

public class OuterClass {


private static String staticOuterField = "Static Outer class field";
private String nonStaticOuterField = "Non-static Outer class field";

// Static nested class


public static class StaticNestedClass {
public void display() {
// Accessing static field of outer class
[Link]("Accessing from Static Nested Class: " + staticOuterField);

// Cannot access non-static members of the outer class directly


// [Link](nonStaticOuterField); // This would cause a compilation error
}
}

public static void main(String[] args) {


// Creating an instance of StaticNestedClass. The outerClass instance is not required
[Link] nested = new [Link]();

// Calling method of StaticNestedClass


[Link]();
}
}
Output:

Accessing from Static Nested Class: Static Outer class field

Explanation:

Non-Static Nested Class (Inner Class): It is tied to an instance of the outer class. It can
access both static and non-static members of the outer class.

Static Nested Class: It can only access static members of the outer class and does not
require an instance of the outer class to be created.
These examples demonstrate how you can use both types of nested classes in Java.

Recursion

In Java programming, recursion is the concept that allows a method to call itself. A method
that calls itself is said to be recursive.

/ A simple example of recursion.


class Factorial {
// this is a recusive function
int fact(int n) {
int result;

if (n == 1) return 1;
result = fact(n - 1) * n;
return result;
}
}

class Recursion {
public static void main(String[] args) {
Factorial f = new Factorial();

[Link]("Factorial of 3 is " + [Link](3));


[Link]("Factorial of 4 is " + [Link](4));
[Link]("Factorial of 5 is " + [Link](5));
}
}

o/p
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 3 is 120

Recursion is a powerful programming technique in Java and other languages. While loops are
often more straightforward and efficient, recursion has several advantages in certain
scenarios. Below are some key advantages of using recursion over loops:

1. Simplicity and Readability


Problem Decomposition: Recursive solutions can closely align with the problem’s natural
structure, especially for problems that are inherently recursive (e.g., tree traversal, factorial
computation). This can make the code easier to write, read, and understand.
Elegance: Recursive solutions often result in more concise and elegant code. For example,
implementing a factorial or Fibonacci sequence using recursion can be more intuitive than
using loops.

2. Reduced Code Size


Less Boilerplate: Recursion can eliminate the need for boilerplate code required by loops,
such as initialization, condition checking, and updating loop counters. This reduction in code
size can lead to fewer opportunities for errors.
Direct Mapping to Mathematical Definitions: Many mathematical functions (like factorial, GCD,
Fibonacci, etc.) are naturally recursive. Implementing them using recursion can directly map
the code to their mathematical definitions, making the
implementation straightforward.

3. Easier to Solve Complex Problems


Divide and Conquer: Recursion is a natural fit for divide-and-conquer algorithms, where a
problem is divided into smaller sub-problems, solved recursively, and combined. Examples
include algorithms like merge sort, quicksort, and binary search.
Tree and Graph Traversal: Recursion is particularly effective for traversing tree and graph
structures, where each node or vertex is processed and then the algorithm proceeds to the
children or adjacent nodes.

4. State Management
Automatic State Management: Each recursive call in Java maintains its own state in the call
stack, which can be particularly useful when trying to manage complex states across multiple
function calls. This can sometimes simplify the logic and reduce the need for additional data
structures.
5. Flexibility
Multiple Recursive Calls: In some problems, you may need to explore multiple paths or
options (e.g., backtracking algorithms). Recursion allows for exploring these options cleanly
by making multiple recursive calls, which might be more cumbersome to handle with loops.

Example: Fibonacci Sequence Using recursion:

public class Fibonacci {


public static int fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}

public static void main(String[] args) {


[Link](fibonacci(5)); // Output: 5
}
}

Using loops:

public class Fibonacci {


public static int fibonacci(int n) {
if (n <= 1) {
return n;
}
int prev1 = 0, prev2 = 1;
for (int i = 2; i <= n; i++) {
int current = prev1 + prev2;
prev1 = prev2;
prev2 = current;
}
return prev2;
}

public static void main(String[] args) {


[Link](fibonacci(5)); // Output: 5
}
}

You might also like