0% found this document useful (0 votes)
1 views57 pages

Java Notes Unit II Java

The document provides an in-depth overview of Object-Oriented Programming (OOP) concepts in Java, including classes, objects, inheritance, polymorphism, abstraction, and encapsulation. It explains the significance of these concepts in Java's architecture and their practical applications through examples. Additionally, it covers the creation and use of constructors, detailing different types such as default, non-parameterized, and parameterized constructors.

Uploaded by

chhandanandi26
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)
1 views57 pages

Java Notes Unit II Java

The document provides an in-depth overview of Object-Oriented Programming (OOP) concepts in Java, including classes, objects, inheritance, polymorphism, abstraction, and encapsulation. It explains the significance of these concepts in Java's architecture and their practical applications through examples. Additionally, it covers the creation and use of constructors, detailing different types such as default, non-parameterized, and parameterized constructors.

Uploaded by

chhandanandi26
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
You are on page 1/ 57

SATHYABMA INSTITUTE OF SCIENCE AND TECHNOLOGY SCHOOL OF COMPUTING

S12BLH31 PROGRAMMING IN JAVA

Unit-II

Java, renowned for its simplicity, reliability, and portability, has been a cornerstone in the
programming landscape for decades, largely due to its effective use of OOP (Object-Oriented
Programming) concepts. The inception of Java, with its oops concepts in java, reshaped how
developers approached programming, offering a platform-independent language that emphasizes
security and simplicity. Through the implementation of what is oops in java, including its
fundamental OOPs concepts like encapsulation, inheritance, and polymorphism, Java’s enduring
popularity in various domains, from web applications to enterprise solutions, is a testament to its
robustness and versatility. The concept of OOPs in java underpins its design philosophy, making
it an ideal language for both beginners learning like the basics of OOPs in java and seasoned
professionals delving into more advanced concepts of oops in java.

Java’s Object-Oriented Programming System (OOPS) is a fundamental aspect of its


architecture, embodying key concepts such as classes, objects, inheritance, polymorphism,
abstraction, and encapsulation. These java oops concepts are crucial for understanding how Java
manages data and executes operations.

What is OOPs Concept?

Object-oriented programming is a core of Java Programming, which is used for designing a


program using classes and objects. OOPs, can also be characterized as data controlling for
accessing the code. In this approach, programmers define the data type of a data structure and the
operations that are applied to the data structure.

Understanding Object-Oriented Concepts in Java:

In the world of Java programming, it’s essential to grasp the fundamental object-oriented
concepts in Java. Object-Oriented Programming, or OOPs in Java, is not just a set of rules; it’s
a powerful paradigm that drives Java’s design and development principles.

Exploring OOPs in Java: So, what exactly is OOPs in Java? Let’s break it down and understand
the concept of OOPs through Java’s core principles.
Objects:

In Java, an object is more than just a runtime entity; it’s the embodiment of a class. These objects
mirror real-world entities, complete with both state and behavior. Think of a ‘Car’ object based on
a ‘Car’ class. It possesses attributes like color, brand, and speed, along with behaviors like
‘accelerate’ and ‘brake’. This is where Java OOP concepts come to life.

Classes:

A class in Java serves as a blueprint for creating objects. It bundles data (attributes) and behavior
(methods) that define the object. Consider a ‘Car’ class; it defines attributes like color and methods
like ‘accelerate()’. Essentially, a class is a template that characterizes what can be instantiated as
an object, exemplifying OOPs concepts.

Abstraction:

Abstraction in Java involves concealing complexity while exposing only the essential
aspects. It’s realized through abstract classes and interfaces. For instance, a ‘Vehicle’ interface
declares a ‘move()’ method, but the actual implementation is left to classes like ‘Car’ or ‘Bike’.
This focus on “what an object does” rather than “how it does it” is a core OOPs concept in Java.

Inheritance:

Inheritance is a mechanism where a new class (subclass) derives attributes and methods
from an existing class (superclass). This fosters code reusability and establishes a hierarchical
relationship between classes. For example, an ‘ElectricCar’ class can inherit traits from the ‘Car’
class, showcasing the practicality of Java OOPs concepts.

Polymorphism:

Polymorphism allows Java methods and objects to assume multiple forms. It finds common
use in method overloading (same method name, different parameters) and method overriding
(same method name and parameters in subclass as in parent class). Consider a ‘draw()’ method
implemented differently in ‘Circle’, ‘Square’, and ‘Triangle’ classes as a prime example
of polymorphism in Java.

Encapsulation:

Encapsulation is a pivotal OOPs principle in Java. It entails bundling data (attributes) and
code (methods) into a cohesive unit. Moreover, it limits direct access to an object’s components,
preventing inadvertent interference. Techniques like using private variables and offering public
getter and setter methods exemplify Java OOPs concepts put into practice.
Java’s strength lies in its adherence to the OOP principles. Understanding the characteristics of
OOPs in Java is pivotal for crafting efficient and modular code. These Java OOPs concepts form
the foundation of modern software development, enabling developers to create elegant and
scalable solutions.

OOPs Concepts in Java with Examples: OOPs Concepts in Java with Examples:

 Class Example: class Car { String color; void accelerate() { ... } }


 Object Example: Car myCar = new Car();
 Inheritance Example: class ElectricCar extends Car { ... }
 Polymorphism Example: Method overloading and overriding.
 Abstraction Example: Abstract classes and interfaces.
 Encapsulation Example: Private fields with public getters and setters.

Classes and Objects

Class
Class is a blueprint or template for its objects that describes characteristics and behaviour.
Each object of the class possesses the characteristics and behaviour (data and functions) described
within the class. A number of objects of a particular class contain different characteristics but they
share common behaviour.

The class and objects can be considered to be the two sides of the same coin, which cannot be
disintegrated. It is insignificant to discuss an object without referring to its 'Class'.
Thus, we can say that Class is simply a representation of similar types of Objects. It is the
blueprint/plan/template that describes the details of an Object.

Object is an instance of a Class.

Class is a blueprint of an object. When a class is defined, it doesn't acquire any space in memory,
it is only the attributes which must be common to all the objects of that class• Moreover, when an
object of a class is created, it includes instance variables described within the class. This is the
reason why an object is called an instance of a class.

Real World Class and Objects

Let us take an example of a class ‘Text_Book’. The different subjects (objects) can be created from
the class ‘Text_Book’ which are as shown below:

Here, each object of the class “Text_Book” will possess different characteristics like name and
publisher but will have common behaviour like reading, preparing for exam and making project.

Syntax

To declare a class in Java, use the following format:

class ClassName {

// class body

}
The name of the class should be followed by the keyword class. The body of the class is enclosed
within curly braces {}.All the data members and member functions of the class are declared inside
the body of the class.

Code example: Let's look at the example of the Java class below:

public class Person


{
// fields
String name;
// methods
void printName()
{
System.out.println(name);
}
}

This Java class has the name Person.The keyword public is an access modifier, which determines
who can access this class. In this case, the class is accessible by any other class. Inside the body
of the class, we can declare fields and methods.

Fields

Fields are variables that contain data. In the example above, we have a field named name.Fields
are usually declared at the top of the class before any methods.

Methods

Methods are functions that perform actions. In the example above, we have a method
named printName(), which prints the value of the name field to the screen.Methods are usually
declared after the fields in a class. To use a class, we need to create an instance of the class. To do
this, we use the keyword new.

Creating objects of a class

Object is also called the instance of the class. When an object of a class is created, then it is said
to be instantiation. All the instances share the state (attribute) and the behaviour described within
the class. But the attributes (i.e., the states) are unique for each object. A single class may have
any number of instances.

Syntax of creating an Object of a Class:

(Class Name><Object Name> = new <Class Name>( );

For example, if we want to create an instance of the Person class, we would use the following
code:

Person myObj = new Person();

Note: new operator- The keyword 'new' is used to allocate space in the dynamic memory for the
storage of data and functions belonging to an object. This creates an object called myObj, which
is an instance of the Person class. We can then access the fields and methods of this object using
the dot notation, like this:

myObj.name = "Sathyabama University";

myObj.printName();

This set the name field to "SathyabamaUniversity" and then call the printName() method, which
print the value of the name field to the screen.

class Person {

// fields

String name;

// methods

void printName() {

System.out.println(name);

}
class Main {

public static void main( String args[] ) {

Person myObj = new Person();

myObj.name = " Sathyabama University ";

myObj.printName();

Let us design a program which includes the object 'Student l' of class 'Performance', describing the
above data members and member methods:

// a program to create object of a class


import java.util. * ;
class Performance
{
int p,c,b,sum;
double avg;
void Accept()
{
Scanner in = new Scanner(System.in);
System.out.println("Enter marks in Physics");
p=in.nextlnt();
System.out.println("Enter marks in Chemistry");
c=in.nextlnt();
System.out.println("Enter marks in Biology");
b=in.nextlnt();
}
void Calculate()
{
sum=p+c+b;
avg=sum/3.0();
}
void Display()
{
System.out.println("TotaI= "+sum);
System.out.println("Average= "+avg);
}
public static void main(String args[])
{
Performance Studentl=new Performance();
Studentl.Accept();
Studentl .Calculate();
Student1.Display();
}
}

Similarly, other objects of the classs ‘Performance’ can be created bu using the following
statements:

Performance Student2= new Performance();


Performance Student3=new Performance();

Each object of class ‘Performance’ created above will contain different data values as Name, marks
in Physics, Chemistry and Biology along with the common functions(methods) as Accept(),
Calculate() and Display().

Constructor
A constructor in Java Programming is a block of code that initializes (constructs) the
state and value during object creation. It is called every time an object with the help of a new ()
keyword is created. Even if you haven’t specified any constructor in the code, the Java compiler
calls a default constructor. The default constructor is used to assign default states and values, such
as 0, null, etc., to the object. The general syntax of a constructor is:
Invoking a Constructor

A constructor can be invoked, at the time of creating an object of a class. The syntax of invoking a
constructor, is as shown below:

<class name> < object name> = new <constructor()>;

For example,

Here, the keyword ‘ob’ creates object of the class Item and invokes constructor to initialize the
current object.

Features of a Constructor
 The constructor is defined with the same name as class name.
With reference to the above example, the method Item( ) has the same name name Item.
Hence. it is a constructor.
 The constructor is used only to initialize the data members/instance variables and will not
to be used for any other task.
 The constructor is automatically called while creating an object. When an object created,
the constructor gets called implicitly. You need not call a constructor through the object
like other member methods.

 For example,

Item 0b = new Item( ); Calling constructor Item( )

 The constructor needs no return type. It is only used to initialize the data members. No
arithmetical or logical operation is performed in a constructor. Hence, return from a
constructor is not at all required.
 The constructor is always public. It is always called from outside the class while creating
an object. Hence, access specifier of a constructor is always public because a private
member method can never be accessed outside the class premises.
 The constructor is overloaded automatically. It means when a number of constructors
created for a class are automatically overloaded as they will possess the same name as the
class name and will contain different type of parameters.

Types of Constructor

There are four different types of constructors which you will learn throughout the discussion.
They are:

(i) Default constructor


(ii) Non-parametrised constructor
(iii) Parameterised constructor
(iv) Copy constructor.

Default Constructor:

A constructor that is used to initialize the instance variables with default initial values, is known
as Default Constructor. When no constructor is defined in a program, the compiler creates a
constructor on its own. As soon as an object of a class is created, it uses this constructor to
initialize the instance variables with system approved initial values.
//A program to illustrate Default Constructor
class Dconst
{
char c;int a;long I;float f;double d;String s;
void display()
{
System.out.println("lnitial value of c="+c);
System.out.println("lnitial value of a="+a);
System.out.println("lnitial value of l="+l);
System.out.println("lnitial value of f="+f);
System.out.println("lnitial value of d="+d);
System.out.println("lnitial value of s="+s);
}

public static void main()


{
Dconst ob= new Dconst();
Ob.display();
}

Non-parametrized constructor

A non-parametrized constructor in Java, also known as a no-argument constructor or default


constructor, is a constructor that does not take any arguments. It is used to initialize objects with
default values.

Here's a simple example to illustrate a non-parametrized constructor:

public class Person {

// Instance variables

String name;
int age;

// Non-parametrised constructor

public Person()

this.name = "Unknown";

this.age = 0;

// Method to display the person's information

public void displayInfo()

System.out.println("Name: " + name);

System.out.println("Age: " + age);

public static void main(String[] args) {

// Creating an object using the non-parametrised constructor

Person person = new Person();

// Displaying the default values

person.displayInfo();

}
Explanation:

1. Class Definition: We define a class named Person with two instance variables, name and
age.

2. Non-parametrized Constructor: We define a non-parametrized constructor Person() that


initializes the name to "Unknown" and age to 0.
3. displayInfo Method: This method prints the name and age of the person.
4. main Method: In the main method, we create an instance of the Person class using the non-
parametrized constructor and then call displayInfo() to print the default values.

When you run this program, it will output:

Name: Unknown
Age: 0

This demonstrates how a non-parametrized constructor is used to set default values for an
object's properties in Java.

Parameterized constructor
A parameterized constructor in Java is a constructor that accepts one or more
parameters, allowing you to initialize an object with specific values. Here’s a simple example
to illustrate a parameterized constructor:
public class Person {
// Instance variables
String name;
int age;
// Parameterised constructor
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
// Method to display the person's information
public void displayInfo()
{
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
public static void main(String[] args)
{
// Creating an object using the parameterised constructor
Person person = new Person("John Doe", 30);
// Displaying the provided values
person.displayInfo();
}
}

Explanation:

1. Class Definition: We define a class named Person with two instance variables, name and
age.

2. Parameterized Constructor: We define a parameterized constructor Person(String name, int


age) that takes name and age as parameters and initializes the instance variables with these
values.
3. displayInfo Method: This method prints the name and age of the person.
4. main Method: In the main method, we create an instance of the Person class using the
parameterized constructor and then call displayInfo() to print the provided values.

When you run this program, it will output:

Name: John Doe


Age: 30

This demonstrates how a parameterized constructor is used to set specific values for an object's
properties in Java.

Copy Constructor

A copy constructor in Java is a special type of constructor used to create a new object as a
copy of an existing object. Although Java does not provide a built-in copy constructor like C++,
you can define one yourself by writing a constructor that takes an object of the same class as a
parameter.

Here’s a simple example to illustrate a copy constructor:

public class Person {


// Instance variables
String name;
int age;

// Parameterised constructor
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
// Copy constructor
public Person(Person another)
{
this.name = another.name;
this.age = another.age;
}
// Method to display the person's information
public void displayInfo()
{
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
public static void main(String[] args)
{
// Creating an object using the parameterised constructor
Person person1 = new Person("John Doe", 30);
// Creating a new object using the copy constructor
Person person2 = new Person(person1);
// Displaying the values of the original object
System.out.println("Original Person:");
person1.displayInfo();
// Displaying the values of the copied object
System.out.println("\nCopied Person:");
person2.displayInfo();
}
}

Explanation:

1. Class Definition: We define a class named Person with two instance variables, name and
age.

2. Parameterized Constructor: We define a parameterized constructor Person(String name,


int age) that takes name and age as parameters and initializes the instance variables with these
values.
3. Copy Constructor: We define a copy constructor Person(Person another) that takes another
Person object as a parameter and initializes the new object’s name and age with the values from

the passed object.


4. displayInfo Method: This method prints the name and age of the person.
5. main Method: In the main method, we create an instance of the Person class using the
parameterized constructor and then create another instance using the copy constructor. We
then call displayInfo() on both objects to print their values.

When you run this program, it will output:


Original Person:
Name: John Doe
Age: 30
Copied Person:
Name: John Doe
Age: 30

This demonstrates how a copy constructor is used to create a new object with the same values as an
existing object in Java.
this keyword

In Java, the this keyword is used to refer to the current object within a method or constructor.
It can be used for various purposes such as distinguishing instance variables from local
variables, invoking other constructors within the same class, or passing the current object as
a parameter.

Here’s a simple example to illustrate the use of this:

public class Person {

// Instance variables

String name;

int age;

// Parameterized constructor

public Person(String name, int age)

// Using 'this' to distinguish between instance variables and parameters

this.name = name;

this.age = age;

// Non-parameterized constructor

public Person()

// Using 'this' to call another constructor

this("Unknown", 0);

// Method to display the person's information

public void displayInfo()


{

System.out.println("Name: " + this.name);

System.out.println("Age: " + this.age);

// Method to compare ages

public boolean isOlderThan(Person other)

// Using 'this' to refer to the current object

return this.age > other.age;

public static void main(String[] args)

// Creating an object using the parameterized constructor

Person person1 = new Person("John Doe", 30);

// Creating an object using the non-parameterized constructor

Person person2 = new Person();

// Displaying the values of both objects

person1.displayInfo();

System.out.println();

person2.displayInfo();

// Comparing ages using the isOlderThan method

System.out.println("\nIs person1 older than person2? " +


person1.isOlderThan(person2));

Explanation:
1. Class Definition: We define a class named Person with two instance variables, name and
age.

2. Parameterized Constructor: We define a parameterized constructor Person(String name,


int age) and use this to distinguish between instance variables and parameters.
3. Non-parameterized Constructor: We define a non-parameterized constructor Person()
and use this to call the parameterized constructor within the same class.
4. displayInfo Method: This method prints the name and age of the person. We use this to
refer to the current object's instance variables.
5. isOlderThan Method: This method compares the age of the current object with another
Person object. We use this to refer to the current object's age.
6. main Method: In the main method, we create two instances of the Person class, one using
the parameterized constructor and one using the non-parameterized constructor. We
then call displayInfo() on both objects and use the isOlderThan method to compare their
ages.

When you run this program, it will output:

Name: John Doe


Age: 30

Name: Unknown
Age: 0

Is person1 older than person2? true

This demonstrates how the this keyword is used in various contexts within a class in Java.

Method Overloading

Method overloading in Java is a feature that allows a class to have more than one
method with the same name, but with different parameter lists. It provides flexibility and
readability in your code by allowing you to call a method in different ways based on the
arguments passed to it.

Here’s a simple example to illustrate method overloading:

public class Calculator {


// Method to add two integers
public int add(int a, int b) {
return a + b;
}
// Overloaded method to add three integers
public int add(int a, int b, int c) {
return a + b + c;
}
// Overloaded method to add two doubles
public double add(double a, double b) {
return a + b;
}
public static void main(String[] args)
{
Calculator calc = new Calculator();
// Calling the add method with two integers
System.out.println("Sum of 10 and 20: " + calc.add(10, 20));

// Calling the overloaded add method with three integers


System.out.println("Sum of 10, 20, and 30: " + calc.add(10, 20, 30));
// Calling the overloaded add method with two doubles
System.out.println("Sum of 10.5 and 20.5: " + calc.add(10.5, 20.5));
}
}

Explanation:

1. Class Definition: We define a class named Calculator.


2. Method Overloading:
o add(int a, int b): Adds two integers.
o add(int a, int b, int c): Adds three integers.
o add(double a, double b): Adds two doubles.
3. main Method: In the main method, we create an instance of the Calculator class and
call the overloaded add methods with different sets of parameters.

When you run this program, it will output:


Sum of 10 and 20: 30
Sum of 10, 20, and 30: 60
Sum of 10.5 and 20.5: 31.0

This demonstrates how method overloading allows a class to have multiple methods with
the same name but different parameter lists, enabling methods to handle different types and
numbers of inputs.

More Complex Example:

Let’s consider a more complex example with a Shape class where method overloading is
used to calculate the area of different shapes:

public class Shape {

// Method to calculate the area of a rectangle

public double area(double length, double width) {

return length * width;

// Overloaded method to calculate the area of a circle

public double area(double radius) {

return Math.PI * radius * radius;

// Overloaded method to calculate the area of a triangle

public double area(double base, double height, boolean isTriangle) {

if (isTriangle) {

return 0.5 * base * height;

}
return 0.0; // default case, not a triangle

public static void main(String[] args) {

Shape shape = new Shape();

// Calculating the area of a rectangle

System.out.println("Area of rectangle (5, 10): " + shape.area(5, 10));

// Calculating the area of a circle

System.out.println("Area of circle (radius 7): " + shape.area(7));

// Calculating the area of a triangle

System.out.println("Area of triangle (base 5, height 10): " + shape.area(5, 10, true));

Explanation:

1. Class Definition: We define a class named Shape.


2. Method Overloading:

o area(double length, double width): Calculates the area of a rectangle.


o area(double radius): Calculates the area of a circle.
o area(double base, double height, boolean isTriangle): Calculates the area of a
triangle, using an additional boolean parameter to distinguish it from the rectangle
method.

3. main Method: In the main method, we create an instance of the Shape class and call
the overloaded area methods with different sets of parameters.

When you run this program, it will output:


Area of rectangle (5, 10): 50.0

Area of circle (radius 7): 153.93804002589985

Area of triangle (base 5, height 10): 25.0

This example demonstrates the flexibility of method overloading, allowing the same
method name to be used for different calculations based on the parameters provided.

Inheritance in Java
It is a term derived from biology which means the transfer of characteristics. Similarly in
Java, some properties of a class is also transferred to another class in order to share data
members or member methods. Hence, a process by which some properties of a class are shared
by another class or classes is known as inheritance.
Let us take a real life example. A child inherits some of the features of his parents. Along
with the inherited traits, he also possesses his own unique characeristics. In this case, parents
can be referred to as Base class and the child inheriting the properties of base class can be
referred to as Derived class. Hence, a base class is a class that is inherited by another class,
but a Derived class or Target or Sub class is one which inherits from a base class. The
following points must be kept in mind when a class inherits from another class:

(i) Private members of the base class cannot be accessed in the derived class.
(ii) Public members of the base class can be used in the derived class.
(iii) Protected members of the base class can be used in the derived class.

Visibility Mode of Inheritance


A base class can be derived by another class by using only the public mode of inheritance.
Public: By using the public mode, the public and Protected members of the class act as the
Public members of the derived class.

The syntax used in Public Inheritance is given below:


public<derived class>
(By default, Base class is Derived public)

The functions geta() and input() will be accessed as the public members of derived class Xyz.
The private data of class Abc, i.e., (data member a) can not be used in the class Xyz (as it is
not accessible outside the class's visibility). Hence, the value of 'a' is returned through a
function input() of the Base class to the add() function of derived class in order to be added
with x.

Base class Abc is derived by Xyz using Public Inheritance

Using Data Members Protected in the Base Class


The class members are declared private to restrict their application within the same
class. A private member of the base class does not have its accessibility to derived class. TO
encourage easy implementation of inheritance, the data members of the class are declared
under protected Visibility so that they can be accessed directly by the derived class.
A class member declared to be protected acts as a Private member for the same class
but can be accessed directly to the derived class.

Illustration to show accessibility of Protected data in the derived class


Types of Inheritance
Inheritance can be used in five different ways, which are explained as:
(a) Single Inheritance: If a base class is derived by a single Target class then it is known as
Single Inheritance.

Java does not support multiple inheritance directly, which means a class cannot extend more than
one class. However, Java provides a way to achieve similar functionality through interfaces.

(b) Hierarchical Inheritance:

Hierarchical inheritance in Java occurs when multiple classes inherit from a single superclass. This
type of inheritance represents a tree-like structure, where the parent class can have multiple child
classes, each of which inherits the properties and methods of the parent class.

Example of Hierarchical Inheritance


Let's create a superclass Animal and three subclasses Dog, Cat, and Bird that inherit from Animal.
// Superclass
class Animal {
String name;
public void eat() {
System.out.println(name + " is eating.");
}
public void sleep() {
System.out.println(name + " is sleeping.");
}
}
// Subclass
class Dog extends Animal {
public void bark() {
System.out.println(name + " is barking.");
}
}
// Another subclass
class Cat extends Animal {
public void meow() {
System.out.println(name + " is meowing.");
}
}
// Another subclass
class Bird extends Animal {
public void fly() {
System.out.println(name + " is flying.");
}
}
public class Main {
public static void main(String[] args) {
// Dog instance
Dog dog = new Dog();
dog.name = "Buddy";
dog.eat(); // Inherited from Animal
dog.sleep(); // Inherited from Animal
dog.bark(); // Defined in Dog
// Cat instance
Cat cat = new Cat();
cat.name = "Whiskers";
cat.eat(); // Inherited from Animal
cat.sleep(); // Inherited from Animal
cat.meow(); // Defined in Cat
// Bird instance
Bird bird = new Bird();
bird.name = "Tweety";
bird.eat(); // Inherited from Animal
bird.sleep(); // Inherited from Animal
bird.fly(); // Defined in Bird
}
}

Explanation:

1. Superclass (Animal):
o Contains a name property.
o Defines two methods: eat and sleep.
2. Subclass (Dog):
o Inherits from Animal.
o Adds a bark method.
3. Another Subclass (Cat):
o Inherits from Animal.
o Adds a meow method.
4. Another Subclass (Bird):
o Inherits from Animal.
o Adds a fly method.
5. Main Method:
o Creates instances of Dog, Cat, and Bird.
o Sets the name property for each instance.
o Calls inherited methods (eat and sleep) and subclass-specific methods (bark, meow, fly).

When you run this program, it will output:


Buddy is eating.
Buddy is sleeping.
Buddy is barking.
Whiskers is eating.
Whiskers is sleeping.
Whiskers is meowing.
Tweety is eating.
Tweety is sleeping.
Tweety is flying.

Consider a real-world example of a company employee hierarchy. We can have a superclass


Employee and subclasses Manager, Engineer, and Intern.

// Superclass
class Employee {
String name;
int id;
public void work() {
System.out.println(name + " is working.");
}
public void attendMeeting() {
System.out.println(name + " is attending a meeting.");
}
}
// Subclass
class Manager extends Employee {
public void manageTeam() {
System.out.println(name + " is managing the team.");
}
}
// Another subclass
class Engineer extends Employee {
public void developSoftware() {
System.out.println(name + " is developing software.");
}
}
// Another subclass
class Intern extends Employee {
public void learn() {
System.out.println(name + " is learning.");
}
}
public class Company {
public static void main(String[] args) {
// Manager instance
Manager manager = new Manager();
manager.name = "Alice";
manager.id = 101;
manager.work(); // Inherited from Employee
manager.attendMeeting(); // Inherited from Employee
manager.manageTeam(); // Defined in Manager

// Engineer instance
Engineer engineer = new Engineer();
engineer.name = "Bob";
engineer.id = 102;
engineer.work(); // Inherited from Employee
engineer.attendMeeting(); // Inherited from Employee
engineer.developSoftware(); // Defined in Engineer
// Intern instance
Intern intern = new Intern();
intern.name = "Charlie";
intern.id = 103;
intern.work(); // Inherited from Employee
intern.attendMeeting(); // Inherited from Employee
intern.learn(); // Defined in Intern
}
}
Explanation:
1. Superclass (Employee):
o Contains properties name and id.
o Defines two methods: work and attendMeeting.
2. Subclass (Manager):
o Inherits from Employee.
o Adds a manageTeam method.
3. Another Subclass (Engineer):
o Inherits from Employee.
o Adds a developSoftware method.
4. Another Subclass (Intern):
o Inherits from Employee.
o Adds a learn method.
5. Main Method:
o Creates instances of Manager, Engineer, and Intern.
o Sets the name and id properties for each instance.
o Calls inherited methods (work and attendMeeting) and subclass-specific methods
(manageTeam, developSoftware, learn).

When you run this program, it will output:


Alice is working.
Alice is attending a meeting.
Alice is managing the team.
Bob is working.
Bob is attending a meeting.
Bob is developing software.
Charlie is working.
Charlie is attending a meeting.
Charlie is learning.

(c) Multiple Inheritance Using Interfaces

An interface in Java is a reference type, similar to a class, that can contain only constants, method
signatures, default methods, static methods, and nested types. Interfaces cannot contain instance
fields or constructors.

By implementing multiple interfaces, a class can achieve multiple inheritance.


Example of Multiple Inheritance Using Interfaces

// First interface
interface CanFly {
void fly();
}
// Second interface
interface CanSwim {
void swim();
}
// A class implementing both interfaces
class Duck implements CanFly, CanSwim {
@Override
public void fly() {
System.out.println("Duck is flying.");
}
@Override
public void swim() {
System.out.println("Duck is swimming.");
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.fly();
duck.swim();
}
}
Explanation:
1. Interface (CanFly): Contains a method signature for fly.
2. Interface (CanSwim): Contains a method signature for swim.
3. Class (Duck): Implements both CanFly and CanSwim interfaces, providing concrete
implementations for the fly and swim methods.
4. Main Method: Creates an instance of Duck and calls its fly and swim methods.
When you run this program, it will output:
Duck is flying.
Duck is swimming.

Using Default Methods in Interfaces

Java 8 introduced default methods in interfaces, which allow methods in interfaces to have a body.
This provides more flexibility when designing interfaces and allows for a form of multiple
inheritance.

// First interface with a default method


interface CanFly {
default void fly() {
System.out.println("Flying.");
}
}
// Second interface with a default method
interface CanSwim {
default void swim() {
System.out.println("Swimming.");
}
}
// A class implementing both interfaces
class Duck implements CanFly, CanSwim {
// The class can choose to override the default methods or use them as is
}
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.fly();
duck.swim();
}
}
Explanation:

1. Interface (CanFly): Contains a default method fly with an implementation.


2. Interface (CanSwim): Contains a default method swim with an implementation.
3. Class (Duck): Implements both CanFly and CanSwim interfaces. The Duck class does not
override the default methods, so it uses the provided implementations.
4. Main Method: Creates an instance of Duck and calls its fly and swim methods.

When you run this program, it will output:


Flying.
Swimming.

Resolving Conflicts with Default Methods

If a class implements multiple interfaces that contain default methods with the same signature,
it must override the conflicting method to resolve the conflict.

// First interface with a default method


interface CanFly {
default void move() {
System.out.println("Flying.");
}
}
// Second interface with a default method
interface CanSwim {
default void move() {
System.out.println("Swimming.");
}
}
// A class implementing both interfaces
class Duck implements CanFly, CanSwim {
// Overriding the conflicting default method
@Override
public void move() {
// You can choose which default method to call
CanFly.super.move();
CanSwim.super.move();
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.move();
}
}

Explanation:

1. Interface (CanFly): Contains a default method move with an implementation.


2. Interface (CanSwim): Contains a default method move with an implementation.
3. Class (Duck): Implements both CanFly and CanSwim interfaces. The Duck class overrides the
move method to resolve the conflict between the default methods. Inside the overridden move
method, it can call the default methods from the interfaces using
InterfaceName.super.methodName().

4. Main Method: Creates an instance of Duck and calls its move method.

When you run this program, it will output:


Flying.
Swimming.

(d) Multi level Inheritance


 In Java (and in other object-oriented languages) a class can get features from another
class. This mechanism is known as inheritance.
 When multiple classes are involved and their parent-child relation is formed in a chained
way then such formation is known as multi-level inheritance.
 In multilevel inheritance, a parent a class has a maximum of one direct child class only.
 In multi-level inheritance, the inheritance linkage is formed in a linear way and minimum
3 classes are involved.
 Code re-usability can be extended with multi-level inheritance.
Example:
class A
{
}
class B extends A
{
}
class C extends B
{
}
Suppose, we have a form as shown above (class A is the parent of class B and class B is
the parent of class C), then features of A are available for B, and features of B (including
that of A) are available for C. So, class C get features of both A and B.
In this case, class B is the parent to C and child to A. such classes are generally known as
intermediate classes. When an object of class C is created, constructors of all the three
classes will be executed.
Even though the control goes to the constructor of C first, the actual sequence of execution
will be the constructor of A first, the constructor of B next and constructor of C at last.
The following example gives a bit more clarity on multi-level inheritance.

Example:

Class Person
{
Person()
{
System.out.println("Person constructor");
}
void nationality()
{
System.out.println("Indian");
}
void place()
{
System.out.println("Mumbai");
}
}
class Emp extends Person
{
Emp()
{
System.out.println("Emp constructor");
}
void organization()
{
System.out.println("IBM");
}
void place()
{
System.out.println("New York");
}
}
class Manager extends Emp
{
Manager()
{
System.out.println("Manager constructor");
}
void subordinates()
{
System.out.println(12);
}
void place()
{
System.out.println("London");
}
}
class Check
{
public static void main(String arg[])
{
Manager m=new Manager();
m.nationality();
m.organization();
m.subordinates();
m.place();
}
}

Output:
Manager constructor
Indian
IBM
12
London

In the above example, as discussed above, the constructor of grandparent class (Person) is
executed first, then parent class (Emp) and then that of child class (Manager).

Then the method nationality() of Person and the method organization() of Emp are accessed
through Manager object as if they are own methods of Manager. Then the
method subordinates() of Manager (its own) is called.

We can see the corresponding outputs here. At last, we have invoked the method place() which
exists in all the three classes. Here, the method of Person is overridden in Emp and the same
method is overridden again in Manager.

So the version in Manager got executed. Had that method been not overridden in Manager, then
the invocation could have executed the Emp version.
 If we don’t want a parent class feature (method or variable) to be available outside the
class then we can make it private.
 In that case, such feature will not be available to child class also.
 If we want to control the accessibility so that they a feature can be accessed in the current
package but not from outside then we make the feature as default (normal).
In the above example, all the methods are normal (default). So they cannot be accessed
from other packages. If we make a feature a protected, then they can be accessed anywhere
in the current package and from child classes of other packages.
If we make a feature as public, then there is no restriction, such elements can be accessed
from anywhere.
In the above example, all the methods are normal (default). So they cannot be accessed from
other packages. If we make a feature a protected, then they can be accessed anywhere in the
current package and from child classes of other packages.
If we make a feature as public, then there is no restriction, such elements can be accessed from
anywhere.
Example:

class X
{
int i;
X()
{
i=5;
}
}
class Y extends X
{
int j;
Y()
{
j=6;
}
}
class Z extends Y
{
int k;
Z()
{
k=7;
}
}
class MultipleInheritanceExample
{
public static void main(String args[])
{
X a=new X(); // class X consist one variable i
Y b=new Y(); // class Y consist variables j, i(it came from parent class X)
Z c=new Z(); //class Z consist variables k,j(class y), i(class X)
System.out.println(a.i); // a-->i=5
System.out.println(b.i+b.j);// b--->i=5,j=6
System.out.println(c.i+c.j+c.k);// c-->i=5,j=6,k=7
}
}

Output:
5
11
18

Hybrid Inheritance:

Hybrid inheritance is a combination of two or more types of inheritance. In Java, hybrid


inheritance is not directly supported due to the absence of multiple inheritance (i.e., a class
cannot inherit from more than one class). However, hybrid inheritance can be achieved using
interfaces.
Example of Hybrid Inheritance Using Interfaces

Let's consider an example where we use both single inheritance and multiple inheritance
through interfaces to achieve hybrid inheritance.

Example Scenario

 We have a superclass Animal with some common methods.


 We have two interfaces CanFly and CanSwim.
 We have a class Bird that inherits from Animal and implements CanFly.
 We have a class Duck that inherits from Bird and implements both CanFly and CanSwim.

// Superclass
class Animal {
String name;
public void eat() {
System.out.println(name + " is eating.");
}
}
// Interface CanFly
interface CanFly {
void fly();
}
// Interface CanSwim
interface CanSwim {
void swim();
}
// Subclass Bird that inherits from Animal and implements CanFly
class Bird extends Animal implements CanFly {
@Override
public void fly() {
System.out.println(name + " is flying.");
}
}
// Subclass Duck that inherits from Bird and implements CanSwim
class Duck extends Bird implements CanSwim {
@Override
public void swim() {
System.out.println(name + " is swimming.");
}}

public class Main {


public static void main(String[] args) {
// Bird instance
Bird bird = new Bird();
bird.name = "Sparrow";
bird.eat(); // Inherited from Animal
bird.fly(); // Implemented from CanFly
// Duck instance
Duck duck = new Duck();
duck.name = "Mallard";
duck.eat(); // Inherited from Animal
duck.fly(); // Inherited from Bird (which implements CanFly)
duck.swim(); // Implemented from CanSwim
}
}
Explanation:

1. Superclass (Animal):
o Contains a name property and an eat method.
2. Interface (CanFly):
o Contains a method signature for fly.
3. Interface (CanSwim):
o Contains a method signature for swim.
4. Subclass (Bird):
o Inherits from Animal.
o Implements the CanFly interface, providing an implementation for the fly method.
5. Subclass (Duck):
o Inherits from Bird.
o Implements the CanSwim interface, providing an implementation for the swim
method.
6. Main Method:
o Creates instances of Bird and Duck.
o Sets the name property for each instance.
o Calls inherited methods (eat and fly) and subclass-specific methods (swim).

When you run this program, it will output


Sparrow is eating.
Sparrow is flying.
Mallard is eating.
Mallard is flying.
Mallard is swimming.

Achieving Hybrid Inheritance in Java


In the above example:
 Bird inherits from Animal and implements CanFly, combining single inheritance and
interface implementation.
 Duck inherits from Bird (which is already inheriting from Animal and implementing
CanFly) and implements CanSwim.
This forms a hybrid inheritance structure where:
 Bird is an example of single inheritance (from Animal) and implementing an
interface (CanFly).
 Duck is an example of single inheritance (from Bird) and implementing another
interface (CanSwim), combining different types of inheritance

Using Super

In Java, the super keyword is used to refer to the immediate parent class object. It can be used
for accessing parent class members (methods and variables) and constructors. This is
particularly useful when working with inheritance, as it allows a subclass to invoke methods
and constructors from its superclass.
Using super to Call Parent Class Methods

When a subclass needs to call a method from its superclass, the super keyword can be used.

class Animal {
String name;
public void eat() {
System.out.println(name + " is eating.");
}
}
// Subclass
class Dog extends Animal {
public void eat() {
super.eat(); // Call the superclass method
System.out.println(name + " is eating dog food.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "Buddy";
dog.eat(); // Calls the overridden method in Dog
}
}

Explanation:

1. Superclass (Animal):
o Contains a name property and an eat method.
2. Subclass (Dog):
o Overrides the eat method.
o Calls the superclass eat method using super.eat() and then adds its own implementation.
3. Main Method:
o Creates an instance of Dog.
o Sets the name property.
o Calls the overridden eat method, which first calls the superclass method and then prints
its own message.

When you run this program, it will output:


Buddy is eating.
Buddy is eating dog food.

Using super to Call Parent Class Constructors


The super keyword can also be used to call a superclass constructor from a subclass constructor.
This is useful when the superclass has a parameterized constructor that needs to be invoked when
creating an instance of the subclass.
// Superclass
class Animal {
String name;
// Parameterized constructor
public Animal(String name) {
this.name = name;
}
public void display() {
System.out.println("Animal's name: " + name);
}
}
// Subclass
class Dog extends Animal {
String breed;
// Parameterized constructor
public Dog(String name, String breed) {
super(name); // Call the superclass constructor
this.breed = breed;
}
public void display() {
super.display(); // Call the superclass display method
System.out.println("Dog's breed: " + breed);
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy", "Golden Retriever");
dog.display(); // Calls the overridden method in Dog
}
}

Explanation:

1. Superclass (Animal):
o Contains a name property.
o Has a parameterized constructor that initializes the name.
o Contains a display method.
2. Subclass (Dog):
o Contains a breed property.
o Has a parameterized constructor that calls the superclass constructor using
super(name).

o Overrides the display method, calling super.display() to display the name from the
superclass, and then displays the breed.
3. Main Method:
o Creates an instance of Dog using the parameterized constructor.
o Calls the display method.

When you run this program, it will output:


Animal's name: Buddy
Dog's breed: Golden Retriever

The super keyword in Java is a powerful feature when dealing with inheritance. It allows
subclasses to:

 Call superclass methods using super.methodName().


 Call superclass constructors using super(arguments).
By using super, subclasses can build on the functionality of their superclasses, enhancing
and extending the behavior in a controlled and structured manner. This promotes code reuse
and helps maintain a clear and organized class hierarchy.

Method Overriding

Method overriding in Java occurs when a subclass provides a specific implementation for
a method that is already defined in its superclass. The method in the subclass should have
the same name, return type, and parameters as the method in the superclass.

Key Points about Method Overriding

1. Same Method Signature: The overridden method must have the same name, return
type, and parameter list as the method in the superclass.
2. Access Modifier: The access level of the overridden method in the subclass cannot be
more restrictive than the method in the superclass.
3. @Override Annotation: It is a good practice to use the @Override annotation, which
helps to ensure that a method is correctly overridden.
4. Dynamic Method Dispatch: Method calls are resolved at runtime based on the
object's actual type, which enables polymorphism.

Example of Method Overriding

Let's create a superclass Animal and a subclass Dog to demonstrate method overriding.

// Superclass
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
// Subclass
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // Animal reference and object
Animal myDog = new Dog(); // Animal reference but Dog object
myAnimal.sound(); // Calls the method from Animal class
myDog.sound(); // Calls the overridden method from Dog class
}
}

Explanation:

1. Superclass (Animal):
o Contains a method sound that prints a generic message.
2. Subclass (Dog):
o Overrides the sound method from Animal with a specific implementation that
prints "Dog barks".
o Uses the @Override annotation to indicate that the method is overriding a
superclass method.
3. Main Method:
o Creates an instance of Animal and calls its sound method.
o Creates an instance of Dog but refers to it using an Animal reference,
demonstrating polymorphism. The overridden sound method in the Dog class is
called.

When you run this program, it will output:

Animal makes a sound

Dog barks

Overriding with Access Modifiers


The access level of the overriding method in the subclass cannot be more restrictive than the
method in the superclass. For example, if the superclass method is public, the overriding method
in the subclass cannot be protected or private.
// Superclass
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
// Subclass
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.sound();
}
}

Summary

Method overriding is a powerful feature in Java that enables polymorphism, allowing a


subclass to provide a specific implementation for a method that is already defined in its
superclass. Key points to remember include:

 The overridden method must have the same name, return type, and parameter list.
 The access level of the overridden method cannot be more restrictive.
 Using the @Override annotation helps ensure correct overriding.
 Covariant return types allow a subclass to override a method and return a subtype of
the declared return type.

By understanding and using method overriding effectively, you can create flexible and
reusable code with clear hierarchical relationships between classes.
Abstract Classes
Abstract classes in Java are classes that cannot be instantiated on their own and are meant to be
subclassed. They can contain abstract methods (methods without an implementation) as well as
concrete methods (methods with an implementation). Abstract classes are used to provide a common
template for subclasses, ensuring that certain methods are implemented in the subclasses while
allowing some shared functionality to be defined in the abstract class itself.

Key Points about Abstract Classes

 Cannot be instantiated: You cannot create an instance of an abstract class directly.


 Can contain both abstract and concrete methods: Abstract methods are declared
without an implementation, while concrete methods have an implementation.
 Must be subclassed: Any subclass of an abstract class must provide implementations
for all abstract methods, unless the subclass is also abstract.
 Can have constructors: Abstract classes can have constructors, which can be called
during the instantiation of the concrete subclass.

Example of Abstract Classes

Let's create an abstract class Animal with both abstract and concrete methods, and two
subclasses Dog and Cat that provide implementations for the abstract methods.

// Abstract superclass

abstract class Animal {


String name;
// Constructor
public Animal(String name) {
this.name = name;
}
// Abstract method (no implementation)
public abstract void sound();
// Concrete method
public void eat() {
System.out.println(name + " is eating.");
}
}
// Subclass
class Dog extends Animal {
// Constructor
public Dog(String name) {
super(name);
}
// Implementing the abstract method
@Override
public void sound() {
System.out.println(name + " barks.");
}
}
// Another subclass
class Cat extends Animal {
// Constructor
public Cat(String name) {
super(name);
}
// Implementing the abstract method
@Override
public void sound() {
System.out.println(name + " meows.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
dog.eat(); // Calls the concrete method in Animal
dog.sound(); // Calls the overridden method in Dog

Cat cat = new Cat("Whiskers");


cat.eat(); // Calls the concrete method in Animal
cat.sound(); // Calls the overridden method in Cat
}
}
Explanation:
Abstract Superclass (Animal):
 Contains a name property.
 Defines a constructor to initialize the name.
 Declares an abstract method sound without an implementation.
 Provides a concrete method eat with an implementation.

Subclass (Dog):
 Inherits from Animal.
 Provides a constructor that calls the superclass constructor using super(name).
 Implements the abstract method sound.
Another Subclass (Cat):
 Inherits from Animal.
 Provides a constructor that calls the superclass constructor using super(name).
 Implements the abstract method sound.
Main Method:
 Creates instances of Dog and Cat.
 Calls the eat method (inherited from Animal).
 Calls the sound method (implemented in the subclasses).

When you run this program, it will output:


Buddy is eating.
Buddy barks.
Whiskers is eating.
Whiskers meows.

Abstract Classes vs. Interfaces


Abstract Classes:
 Can contain both abstract and concrete methods.
 Can have instance variables and constructors.
 A class can extend only one abstract class (single inheritance).
Interfaces:
 Can contain abstract methods and default methods (methods with a body).
 Cannot have instance variables or constructors.
 A class can implement multiple interfaces (multiple inheritance).

When to Use Abstract Classes


 When you want to share code among several closely related classes.
 When you expect classes that extend your abstract class to have many common
methods or fields, or require access modifiers other than public (such as protected
and private).
 When you want to define non-static or non-final fields.

Summary

Abstract classes in Java provide a way to define a common template for related classes,
ensuring that certain methods are implemented in the subclasses while allowing for
shared functionality. By understanding and using abstract classes effectively, you can
create a clear and organized class hierarchy, promote code reuse, and ensure that
subclasses adhere to a defined contract.

Using final with inheritance

In Java, the final keyword can be used in various contexts, and it has different meanings
depending on where it is applied. When used with inheritance, final can be applied to
classes, methods, and variables to enforce specific restrictions.

Using final with Classes

When a class is declared as final, it cannot be subclassed. This means no other class can
extend a final class. This is useful when you want to prevent inheritance for security
reasons or to ensure the integrity of the class's behavior.

// Final class
final class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
// The following class declaration will cause a compile-time error
// class Dog extends Animal {
// public void sound() {
// System.out.println("Dog barks");
// }
// }
public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
animal.sound();
}
}

Using final with Methods

When a method is declared as final, it cannot be overridden by subclasses. This is useful when
you want to ensure that the implementation of the method remains unchanged across all
subclasses.

class Animal {
public final void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
// The following method declaration will cause a compile-time error
// public void sound() {
// System.out.println("Dog barks");
// }
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // Calls the final method from Animal class
}
}
Using final with Variables
When a variable is declared as final, it can be assigned only once. This is useful for defining
constants or ensuring that the value of the variable cannot be changed after it is initialized.
class Animal {
// Final variable
public final String name;
// Constructor to initialize the final variable
public Animal(String name) {
this.name = name;
}
public void display() {
System.out.println("Animal's name: " + name);
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal("Buddy");
animal.display();
// The following assignment will cause a compile-time error
// animal.name = "Max";
}
}
Summary of final Keyword Usage in Inheritance
1. Final Classes:
 Prevents the class from being subclassed.
 Ensures that no one can extend the class and alter its behavior.

2. Final Methods:
 Prevents the method from being overridden by subclasses.
 Ensures that the method's implementation remains consistent across all subclasses.
3. Final Variables:
 Prevents the variable from being reassigned after it has been initialized.
 Useful for defining constants or immutable data.

By using the final keyword appropriately, you can enforce specific constraints in your Java
programs, ensuring that classes, methods, and variables are used as intended and maintaining
the integrity of your code.

Garbage collection

Garbage collection in Java is the process of automatically identifying and discarding objects
that are no longer needed by the program, freeing up memory resources. Java's garbage
collection mechanism helps manage memory efficiently and reduces the risk of memory leaks.

Key Points about Garbage Collection

1. Automatic Memory Management: Java handles memory allocation and deallocation


automatically, so developers don't need to manually manage memory.
2. Garbage Collector: The garbage collector runs in the background and reclaims memory by
identifying and collecting objects that are no longer reachable from any live thread.
3. Reachability: An object is considered garbage if it is not reachable from any reference chain
starting from the root references (such as local variables, active threads, and static fields).

Example of Garbage Collection

Here's a simple example to illustrate how garbage collection works in Java:


public class GarbageCollectionExample {
// A simple class with a finalize method
static class MyObject {
@Override
protected void finalize() throws Throwable {
System.out.println("MyObject is being garbage collected");
}
}
public static void main(String[] args) {
// Creating an object
MyObject obj1 = new MyObject();
// Making the object eligible for garbage collection
obj1 = null;
// Requesting JVM to run Garbage Collector
System.gc();
// Adding a delay to give Garbage Collector time to run
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End of main method");
}
}
Explanation:
1. Class with finalize Method:
 The MyObject class overrides the finalize method, which is called by the garbage collector
before reclaiming the object's memory. This method is used here to print a message
indicating that the object is being garbage collected.
2. Main Method:
 An instance of MyObject (obj1) is created.
 The reference to obj1 is set to null, making the object eligible for garbage collection
because there are no longer any references to it.
 The System.gc() method is called to suggest that the JVM run the garbage collector. Note
that calling System.gc() does not guarantee that the garbage collector will run immediately.
 A delay is added using Thread.sleep(1000) to give the garbage collector some time to run
before the program exits.

Output:
When you run the program, you might see the following output:
MyObject is being garbage collected
End of main method
Important Notes:

1. Non-deterministic: Garbage collection in Java is non-deterministic, meaning you cannot


predict exactly when an object will be collected. The System.gc() call is just a request, not a
command.
2. Finalization: The finalize method is called by the garbage collector before collecting an object.
However, its use is generally discouraged because it introduces unpredictability and potential
performance issues. It's better to use other resource management techniques, such as try-with-
resources for managing resources like files and sockets.
3. Performance: The garbage collector runs in its own thread and may affect application
performance. Java provides various garbage collection algorithms and tuning parameters to
optimize performance for different use cases.

Summary:

Garbage collection in Java is a crucial feature that automates memory management, allowing
developers to focus on writing code without worrying about memory leaks. By understanding
how garbage collection works and using best practices for resource management, you can
write efficient and robust Java applications.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy