UNIT II
public class MyClass {
// Fields
private int age;
private String name;
// Constructor
public MyClass(int age, String name) {
this.age = age;
this.name = name;
// Method
public void displayInfo() {
System.out.println("Name: " + name + ", Age: " + age);
// Main method (for demonstration)
public static void main(String[] args) {
// Creating an object of MyClass
MyClass myObject = new MyClass(25, "John");
// Calling a method on the object
myObject.displayInfo();
The MyClass class is defined with two private fields age and name.
It has a constructor MyClass(int age, String name) to initialize the fields.
There’s a method displayInfo() to display information about the object.
In the main() method, an object of MyClass named myObject is created, and
the displayInfo() method is called on it to print the information.
ClassName objectName = new ClassName();
Car myCar = new Car();
Here, Car is the class name, myCar is the object name, and new Car() instantiates a new
object of the Car class.
Initializing an object
In Java, we can initialize objects in 3 ways-
By reference variable
By method
By constructor
By reference variable– Initialization of an object means storing the data in the object. Let us
understand this with an example-
public class MyClass {
public static void main(String[] args) {
// Initialize the object by reference variable in a single line
MyClass myObject = new MyClass();
// Access methods or fields of the object
myObject.myMethod();
public void myMethod() {
System.out.println("Object initialized successfully!");
In this code, myObject is the reference variable, and it’s initialized to refer to a new object of
the MyClass class in a single line using the new keyword. This single line achieves both
declaration and instantiation of the object. After initialization, you can directly access
methods or fields of the object using the reference variable.
public class Car {
// Attributes
private String brand;
private String model;
private int year;
// Constructor
public Car(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
// Method to display car details
public void displayDetails() {
System.out.println("Brand: " + brand);
System.out.println("Model: " + model);
System.out.println("Year: " + year);
public static void main(String[] args) {
// Creating an object of Car class
Car myCar = new Car("Toyota", "Camry", 2022);
// Calling method to display car details
myCar.displayDetails();
ACCESS MODIFIERS:
In Java, access modifiers are essential tools that define how the
members of a class, like variables, methods, and even the class itself,
can be accessed from other parts of our program. They are an
important part of building secure and modular code when designing
large applications. In this article, we will explore each modifier with
examples to demonstrate its impact on Java development.
Types of Access Modifiers
There are 4 types of access modifiers available in Java:
1. Default - No keyword required
2. Private
3. Protected
4. Public
Algorithm to Use Access Modifier in Java
Here's a basic algorithm for using access modifiers in Java:
1. Define a class: Create a class to represent the object you want to
manage.
2. Define instance variables: Inside the class, define variables for the
data you want to manage.
3. Set an access modifier:
Use private for variables only accessible within the class.
Use protected for variables accessible within the class and its
subclasses.
Use public for variables accessible from anywhere.
4. Use getter and setter methods: To access or modify variables, use
getter (accessor) and setter (mutator) methods, even for public
variables, to maintain encapsulation.
1. Default Access Modifier
When no access modifier is specified for a class, method, or data
member, it is said to have the default access modifier by default. This
means only classes within the same package can access it.
Example 1: Demonstrating Default Access Modifier Within the Same
Package
In this example, we will create two packages and the classes in the
packages will be having the default access modifiers and we will try
to access a class from one package from a class of the second
package.
// default access modifier
package p1;
// Class prg1 is having
// Default access modifier
class prg1
{
void display()
{
System.out.println("Hello World!");
}
}
package p2;
import p1.*; // importing package p1
// This class is having
// default access modifier
class prg2 {
public static void main(String args[]) {
// Accessing class Geek from package p1
Prg1 o = new prg1();
o.display();
}
}
Explanation: In this example, the program will show the compile-
time error when we try to access a default modifier class from a
different package.
2. Private Access Modifier
The private access modifier is specified using the keyword
private. The methods or data members declared as private are
accessible only within the class in which they are declared.
Any other class of the same package will not be able to access
these members.
Top-level classes or interfaces can not be declared as private
because, private means "only visible within the enclosing class".
Protected means "only visible within the enclosing class and
any subclasses".
These modifiers in terms of application to classes, apply only
to nested classes and not on top-level classes.
Example: In this example, we will create two classes A and B within
the same package p1. We will declare a method in class A as private
and try to access this method from class B and see the result.
package p1;
// Class A
class A {
private void display() {
System.out.println("How are you");
}
}
// Class B
class B {
public static void main (String args[]) {
A obj = new A();
// Trying to access private method
// of another class
obj.display();
}
}
Explanation: The above code will show a compile-time error when
trying to access a private method from class B, even within the same
package.
3. Protected Access Modifier
The protected access modifier is specified using the keyword
protected. The methods or data members declared as protected are
accessible within the same package or subclasses in different
packages.
Example 1: In this example, we will create two packages p1 and p2.
Class A in p1 is made public, to access it in p2. The method display in
class A is protected and class B is inherited from class A and this
protected method is then accessed by creating an object of class B.
package p1;
// Class A
public class A {
protected void display() {
System.out.println("B.Tech III Semester");
}
}
So, it demonstrates that a protected method is accessible within the
same package.
Example 2:
In this example, we will create two packages, p1 and p2. Class A in
p1 has a protected method display. Class B in p2 extends A and
accesses the protected method through inheritance by creating an
object of class B.
package p2;
// importing all classes
// in package p1
import p1.*;
// Class B is subclass of A
class B extends A {
public static void main(String args[]) {
B obj = new B();
obj.display();
}
}
Explanation: The above example demonstrates that a protected
method is accessible in a subclass from a different package using
inheritance.
4. Public Access Modifier
The public access modifier is specified using the keyword public.
The public access modifier has the widest scope among all
other access modifiers.
Classes, methods, or data members that are declared as public
are accessible from everywhere in the program. There is no
restriction on the scope of public data members.
Example 1: Here, the code shows that a public method is accessible
within the same package.
package p1;
public class A {
public void display() {
System.out.println("GeeksforGeeks");
}
}
Important Points:
If other programmers use your class, try to use the most
restrictive access level that makes sense for a particular
member.
Avoid public fields except for constants.
Comparison Table of Access Modifiers in
Java
Defau Priva Protect Publi
Context lt te ed c
Same Class Yes Yes Yes Yes
Same Package Subclass Yes No Yes Yes
Defau Priva Protect Publi
Context lt te ed c
Same Package Non-
Yes No Yes Yes
Subclass
Different Package Subclass No No Yes Yes
Different Package Non-
No No No Yes
Subclass
JAVA METHODS:
Java Methods are blocks of code that perform a specific task. A method allows
us to reuse code, improving both efficiency and organization. All methods in
Java must belong to a class. Methods are similar to functions and expose the
behavior of objects.
public class Btech
{
public void printMessage() {
System.out.println("Hello, Btech!");
}
public static void main(String[] args) {
// Create an instance of the Method class
Btech obj = new Btech();
// Calling the method
obj.printMessage();
}
}
Syntax of a Method
Below image describes the basic syntax of method:
Key Components of a Method Declaration
Method consists of a modifier (Define access level), return type (what value
returned or void), name (Define the name of method follows camelCase),
parameters (optional inputs), and a body (Write your logic here).
Why Do We Break Code into Methods?
Breaking code into separate methods helps improve readability, reusability, and
maintainability
Reusability: Write once, use multiple times without repeating code so
that code reusability increase.
Readability: Smaller, named methods make the code easier to read and
understand.
Maintainability: It’s easier to fix bugs or update code when it's organized
into methods.
Testing: Methods can be tested independently, improving code reliability
and easier debugging.
Constructor Overloading in Java
Java supports Constructor Overloading in addition to overloading methods. In
Java, overloaded constructor is called based on the parameters specified when
a new is executed.
When do we need Constructor Overloading?
Sometimes there is a need of initializing an object in different ways. This can be
done using constructor overloading.
For example, the Thread class has 8 types of constructors. If we do not want to
specify anything about a thread then we can simply use the default constructor
of the Thread class, however, if we need to specify the thread name, then we
may call the parameterized constructor of the Thread class with a String args
Thread t= new Thread (" MyThread ");
// An example class to understand need of
// constructor overloading.
class Box
{
double width, height,depth;
// constructor used when all dimensions
// specified
Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
}
// compute and return volume
double volume()
{
return width * height * depth;
}
}
As we can see that the Box() constructor requires three parameters. This
means that all declarations of Box objects must pass three arguments to the
Box() constructor.
For example, the following statement is currently invalid:
Box ob = new Box();
Since Box() requires three arguments, it’s an error to call it without them.
Suppose we simply wanted a box object without initial dimension, or want to
initialize a cube by specifying only one value that would be used for all three
dimensions. From the above implementation of the Box class, these options
are not available to us. These types of problems of different ways of initializing
an object can be solved by constructor overloading.
Example of Constructor Overloading
Below is the improved version of class Box with constructor overloading.
class Box
{
double width, height, depth;
// constructor used when all dimensions
// specified
Box(double w, double h, double d)
{
width = w;
height = h;
depth = d;
}
Constructor Overloading:
// constructor used when no dimensions
// specified
Box() { width = height = depth = 0; }
// constructor used when cube is created
Box(double len) { width = height = depth = len; }
// compute and return volume
double volume() { return width * height * depth; }
}
// Driver code
public class Test {
public static void main(String args[])
{
// create boxes using the various
// constructors
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box();
Box mycube = new Box(7);
double vol;
// get volume of first box
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
// get volume of second box
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
// get volume of cube
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
}
}
Using this() in Constructor Overloading
this() reference can be used during constructor overloading to call the default
constructor implicitly from the parameterized constructor.
// Java program to illustrate role of this() in
// Constructor Overloading
public class Box
{
double width, height, depth;
int boxNo;
// constructor used when all dimensions and
// boxNo specified
Box(double w, double h, double d, int num)
{
width = w;
height = h;
depth = d;
boxNo = num;
}
// constructor used when no dimensions specified
Box()
{
// an empty box
width = height = depth = 0;
}
// constructor used when only boxNo specified
Box(int num)
{
// this() is used for calling the default
// constructor from parameterized constructor
this();
boxNo = num;
}
public static void main(String[] args)
{
// create box using only boxNo
Box box1 = new Box(1);
// getting initial width of box1
System.out.println(box1.width);
}
}
Output
0.0
As we can see in the above program we called Box(int num) constructor during
object creation using only box number. By using this() statement inside it, the
default constructor(Box()) is implicitly called from it which will initialize the
dimension of Box with 0.
For example, the following fragment is invalid and throws compile time error.
Box(int num)
{
boxNo = num;
/* Constructor call must be the first
statement in a constructor */
this (); /*ERROR*/
}
Important points to be taken care of while doing Constructor Overloading
Constructor calling must be the first statement of the constructor in Java.
If we have defined any parameterized constructor, then the compiler will
not create a default constructor. and vice versa if we don’t define any
constructor, the compiler creates the default constructor(also known as
no-arg constructor) by default during compilation
Recursive constructor calling is invalid in Java.
INHERITANCE:
Inheritance is an object-oriented programming concept in which one
class acquires the properties and behavior of another class. It represents
a parent-child relationship between two classes. This parent-child
relationship is also known as an IS-A relationship.
Subclass
A subclass, also known as child class or derived class, is the class that
inherits the properties and behaviors of another class. So, if A and B are
two classes and if B class inherits A class, then the B class is called the
subclass Superclass
A superclass, also known as parent class or base class, is the class whose
properties and behaviors are inherited by the subclass. So, if A and B are
two classes and if B class inherits A class, then A class is called the
superclass.
Program:
// Superclass
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Subclass
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Btech {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat(); // Output: Animal is eating
myDog.bark(); // Output: Dog is barking
}
}
OUTPUT:
Animal is eating
Dog is barking
When myDog.eat() is called, it invokes the eat() method inherited from
the Animal superclass. So, it prints “Animal is eating”.
When myDog.bark() is called, it invokes the bark() method defined in
the Dog subclass. So, it prints “Dog is barking”.
How to achieve/implement inheritance in Java?
Let us list out a few of the terms and keywords generally used in
inheritance.
Subclass: The class that inherits the attributes and methods of another
class.
Superclass: The class whose attributes and methods the subclass
inherits.
Extends: The subclass uses the keyword to inherit the superclass.
Reusability: The methods and attributes of the superclass can be reused
in the subclass because of inheritance, this is called reusability.
Program2:
// Superclass
class Vehicle {
private String brand;
private int year;
public Vehicle(String brand, int year) {
this.brand = brand;
this.year = year;
}
public void drive() {
System.out.println("Driving the " + year + " " + brand);
}
}
// Subclass
class Car extends Vehicle {
private int numDoors;
public Car(String brand, int year, int numDoors) {
super(brand, year); // Call superclass constructor
this.numDoors = numDoors;
}
public void honk() {
System.out.println("Honking the horn of the " + getYear() + " " +
getBrand());
}
public int getNumDoors() {
return numDoors;
}
}
public class Btech {
public static void main(String[] args) {
Car myCar = new Car("Toyota", 2020, 4);
// Accessing superclass method
myCar.drive(); // Output: Driving the 2020 Toyota
// Accessing subclass methods and inherited methods
myCar.honk(); // Output: Honking the horn of the 2020 Toyota
System.out.println("Number of doors: " + myCar.getNumDoors()); //
Output: Number of doors: 4
}
}
OUTPUT:
Driving the 2020 Toyota
Honking the horn of the 2020 Toyota
Number of doors: 4
myCar.drive() invokes the drive() method inherited from
the Vehicle superclass, which prints “Driving the 2020 Toyota”.
myCar.honk() invokes the honk() method defined in the Car subclass,
which prints “Honking the horn of the 2020 Toyota”.
System.out.println("Number of doors: " + myCar.getNumDoors()) prints
the number of doors of the car, which is 4.
Types of Inheritance in Java
1. Single Inheritance
2. Multi-level Inheritance
3. Hierarchical Inheritance
4. Hybrid Inheritance
1. Single Inheritance
Single inheritance in Java refers to the inheritance relationship where a
subclass extends only one superclass. Here’s an example
demonstrating single inheritance.
// Superclass
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Subclass (Single Inheritance)
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
// Accessing superclass method
myDog.eat(); // Output: Animal is eating
// Accessing subclass method
myDog.bark(); // Output: Dog is barking
}
}
OUTPUT:
Animal is eating
Dog is barking
2. Multi-level Inheritance
Multi-level inheritance in Java refers to a scenario where a class inherits
properties and behaviors from another class, which in turn inherits from
another class. This creates a hierarchical structure of classes where each
class inherits from the one above it.
Program:
// Parent class
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Child class inheriting from Animal
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
// Sub-child class inheriting from Dog
class Labrador extends Dog {
void display() {
System.out.println("Labrador is a type of Dog");
}
}
public class Main {
public static void main(String[] args) {
Labrador labrador = new Labrador();
labrador.eat(); // Inherited from Animal
labrador.bark(); // Inherited from Dog
labrador.display(); // Defined in Labrador class
}
}
OUTPUT:
Animal is eating
Dog is barking
Labrador is a type of Dog
3. Hierarchical Inheritance
Hierarchical inheritance in Java refers to a scenario where multiple
classes inherit properties and behaviors from a single parent class. In this
inheritance structure, there is one parent class and multiple child classes
that inherit from it.
Program:
// Parent class
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Child class 1 inheriting from Animal
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
// Child class 2 inheriting from Animal
class Cat extends Animal {
void meow() {
System.out.println("Cat is meowing");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Inherited from Animal
dog.bark(); // Defined in Dog class
Cat cat = new Cat();
cat.eat(); // Inherited from Animal
cat.meow(); // Defined in Cat class
}
}
Output
Animal is eating
Dog is barking
Animal is eating
Cat is meowing
4. Hybrid Inheritance
Hybrid inheritance in Java refers to a combination of multiple inheritance
and hierarchical inheritance. In hybrid inheritance, a class is derived from
two or more classes, and these derived classes can further have their
own subclasses. Java doesn’t support multiple inheritance directly due to
the diamond problem, but hybrid inheritance can be achieved by
combining hierarchical inheritance and interface implementation.
Program:
// Parent class
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Child class 1 inheriting from Animal
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
// Child class 2 inheriting from Animal
class Cat extends Animal {
void meow() {
System.out.println("Cat is meowing");
}
}
// Interface defining behavior for domestic animals
interface Domestic {
void play();
}
// Sub-interface for specific type of domestic animals
interface DogBehavior extends Domestic {
void guard();
}
// Class implementing Domestic and DogBehavior interfaces
class DomesticDog implements DogBehavior {
public void play() {
System.out.println("Domestic dog is playing");
}
public void guard() {
System.out.println("Domestic dog is guarding");
}
}
public class Main {
public static void main(String[] args) {
DomesticDog dog = new DomesticDog();
dog.play(); // Defined in Domestic interface
dog.guard(); // Defined in DogBehavior interface
}
}
Output
Domestic dog is playing
Domestic dog is guarding
Extends vs Implements in Java
In Java, the extends keyword is used to inherit all the properties and
methods of the parent class while the implements keyword is used to
implement the method defined in an interface.
S.No
. Extends Implements
By using "extends"
keyword a class can By using "implements"
1. inherit another class, or keyword a class can
an interface can inherit implement an interface
from other interfaces
It is not compulsory for It is compulsory for a
a subclass that extends class implementing an
2. a superclass to override interface to implement
all the methods in a all the methods of that
superclass. interface.
3. A class can extend only A class can implement
one super class any number of an
interface at the same
S.No
. Extends Implements
time
An interface can extend
Any number of
other interfaces but
4. interfaces can be
cannot implements
extended by interface.
them.
"extends" Keyword in Java
In Java, the extends keyword is used to indicate that the class which is
being defined is derived from the base class using inheritance. So
basically, extends keyword is used to extend the functionality of the
parent class to the subclass. In Java, multiple inheritances are not
allowed due to ambiguity. Therefore, a class can extend only one class
to avoid ambiguity.
Program:
class One {
public void methodOne()
{
// Some Functionality
}
}
class Two extends One {
public static void main(String args[])
{
Two t = new Two();
// Calls the method one
// of the above class
t.methodOne();
}
}
Note: A class can extend a class and can implement any number of
interfaces simultaneously.
"implements" Keyword in Java
In Java, the implements keyword is used to implement an interface. An
interface is a special type of class which implements a complete
abstraction and only contains abstract methods. To access the interface
methods, the interface must be "implemented" by another class with the
implements keyword and the methods need to be implemented in the
class which is inheriting the properties of the interface. Since an
interface is not having the implementation of the methods, a class can
implement any number of interfaces at a time.
// Defining an interface
interface One {
public void methodOne();
}
// Defining the second interface
interface Two {
public void methodTwo();
}
// Implementing the two interfaces
class Three implements One, Two {
public void methodOne()
{
// Implementation of the method
}
public void methodTwo()
{
// Implementation of the method
}
}
Note: An interface can extend any number of interfaces at a time.
Program:
// Defining the interface One
interface One {
void methodOne();
}
// Defining the interface Two
interface Two {
void methodTwo();
}
// Interface extending both the
// defined interfaces
interface Three extends One, Two {
}
Overriding in Java occurs when a subclass or child class implements a
method that is already defined in the superclass or base class. When a
subclass provides its own version of a method that is already defined in
its superclass, we call it method overriding. The subclass method must
match the parent class method's name, parameters, and return type.
Rules for Overriding:
Name, parameters, and return type must match the parent method.
Java picks which method to run, based on the actual object type, not just
the variable type.
Static methods cannot be overridden.
The @Override annotation catches mistakes like typos in method
names.
Animal {
// Base class
void move()
{ System.out.println(
"Animal is moving.");
}
void eat() {
System.out.println( "Animal is eating."); }
}
class Dog extends Animal {
@Override void move()
{ // move method from Base class is overriden in this
// method
System.out.println("Dog is running.");
}
void bark() { System.out.println("Dog is barking."); }
}
public class Geeks {
public static void main(String[] args)
{
Dog d = new Dog();
d.move(); // Output: Dog is running.
d.eat(); // Output: Animal is eating.
d.bark(); // Output: Dog is barking.
}
}
Explanation: The Animal class defines base functionalities
like move() and eat(). The Dog class inherits from Animal
and overrides the move() method to provide a specific behavior Dog is
running. Both classes can access their own methods. When creating a
Dog object, calling move() executes the overridden method.
Explanation: The Animal class defines base functionalities
like move() and eat(). The Dog class inherits from Animal
and overrides the move() method to provide a specific behavior Dog is
running. Both classes can access their own methods. When creating a
Dog object, calling move() executes the overridden method.
Note: Method overriding is a key concept in Java that enables Run-
time polymorphism. It allows a subclass to provide its specific
implementation for a method inherited from its parent class.
Example: This example demonstrates runtime polymorphism in Java,
where the show() method is overridden in the Child class, and the
method called depends on the object type at runtime.
// method overriding in java
class Parent {
// base class or superclass which is going to overriden
// below
void show() { System.out.println("Parent's show()"); }
}
// Inherited class
class Child extends Parent {
// This method overrides show() of Parent
@Override void show()
{
System.out.println("Child's show()");
}
}
// Driver class
class Geeks {
public static void main(String[] args)
{
// If a Parent type reference refers
// to a Parent object, then Parent's
// show is called
Parent obj1 = new Parent();
obj1.show();
// If a Parent type reference refers
// to a Child object Child's show()
// is called. This is called RUN TIME
// POLYMORPHISM.
Parent obj2 = new Child();
obj2.show();
}
}