Java Class Fundamentals and Examples
Java Class Fundamentals and Examples
#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));
}
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];
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.
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
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;
class Box {
double width;
double height;
double depth;
class BoxDemo3 {
public static void main(String[] args) {
Box mybox1 = new Box();
Box mybox2 = new Box();
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:
class Box {
double width;
double height;
double depth;
class BoxDemo4 {
public static void main(String[] args) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
Setting a Method That Takes Parameters with void and return result using returning
value
class Box1 {
double width;
double height;
double depth;
class BoxDemo5 {
public static void main(String[] args) {
Box1 mybox1 = new Box1();
Box1 mybox2 = new Box1();
double 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.
package Second;
/* Here, Box uses a constructor to initialize the
dimensions of a box.
*/
class Box2 {
double width;
double height;
double 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;
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.
package Second;
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;
o/p
Volume is 3000.0
Volume is 162.0
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;
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;
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 {
o/p
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.
Rule 1: Methods need to have the same name with distinct number of parameters in a
single class.
//Overloading method
public int multiply(int num1, int num2, int num3) //method with different number of
parameters
{
return num1 * num2* num3;
}
}
Rule 3 :Attempting to perform overloading based on the return type is not allowed,
Code
// 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.
package Second;
//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;
o/p
Volume of mybox1 is 3000.0
Volume of mybox2 is 0.0
Volume of mycube is 343.0
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.
// Adding a delay to ensure garbage collection occurs before the program ends
try {
[Link](1000);
} catch (InterruptedException e) {
[Link]();
}
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
// Sub Class
class volume
{
private int side;
o/p
The Volume of cube is 125
// Main Class
public class Main_Class2
{
private int side;
o/p
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,
Test(int i, int j) {
a = i;
b = j;
}
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);
o/p
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.
Passing Arguments
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.
package Basic;
class CallbyValue {
public static void main(String[] args) {
Test2 ob = newAccess Control, Test2();
int a = 15, b = 20;
[Link](a, b);
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;
}
class PassObjRef {
public static void main(String[] args) {
Test1 ob = new Test1(15, 20);
[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
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
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)
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.
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.
package Second;
[Link]();
[Link]();
}
}
o/p
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;
Static_Counter()
{
count++;
[Link](count);
}
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]())
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 method
static int add(int a, int b){
return a + b;
}
}
[Link]();
[Link]();
}
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
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.
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");}
}
If you don't use any modifier, it is treated as default bydefault. The default modifier is
accessible only within package.
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 [Link]
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();//Compile Time Error
[Link]();//Compile Time Error
}
}
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.
//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
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
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.
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
If you make any variable as final, you cannot change the value of final variable(It will be
constant).
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.
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.
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.
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.
if (n == 1) return 1;
result = fact(n - 1) * n;
return result;
}
}
class Recursion {
public static void main(String[] args) {
Factorial f = new Factorial();
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:
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.
Using loops: