0% found this document useful (0 votes)
2 views79 pages

Java Unit-3

The document provides a comprehensive overview of arrays in Java, including their declaration, initialization, memory storage, and operations such as sorting and searching. It also covers inheritance and interfaces in Java, explaining concepts like multilevel inheritance, method overriding, and the use of interfaces for implementing multiple behaviors. Key advantages and disadvantages of arrays are discussed, along with examples of sorting algorithms and searching techniques.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views79 pages

Java Unit-3

The document provides a comprehensive overview of arrays in Java, including their declaration, initialization, memory storage, and operations such as sorting and searching. It also covers inheritance and interfaces in Java, explaining concepts like multilevel inheritance, method overriding, and the use of interfaces for implementing multiple behaviors. Key advantages and disadvantages of arrays are discussed, along with examples of sorting algorithms and searching techniques.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd

UNIT III: Arrays:Introduction, Declaration and Initialization of Arrays, Storage of

Array in Computer Memory, Accessing Elements of Arrays, Operations on Array


Elements, Assigning Array to Another Array, Dynamic Change of Array Size,
Sorting of Arrays, Search for Values in Arrays, Class Arrays, Two-dimensional
Arrays, Arrays of Varying Lengths, Three-dimensional Arrays, Arrays as Vectors.
Inheritance:Introduction, Process of Inheritance, Types of Inheritances, Universal
Super Class-Object Class, Inhibiting Inheritance of Class Using Final, Access
Control and Inheritance, Multilevel Inheritance, Application of Keyword Super,
Constructor Method and Inheritance, Method Overriding, Dynamic Method
Dispatch, Abstract Classes, Interfaces and Inheritance.
Interfaces:Introduction, Declaration of Interface, Implementation of Interface,
Multiple Interfaces, Nested Interfaces, Inheritance of Interfaces, Default Methods
in Interfaces, Static Methods in Interface, Functional Interfaces, Annotations.

Arrays:

Java array is an object which contains elements of a similar data type.


Additionally, the elements of an array are stored in a contiguous memory location.
It is a fundamental data structure used to store a fixed-size, sequential collection
of elements of the same data type. Arrays are objects in Java, meaning they
inherit from the [Link] class and reside in the heap memory.

Advantages

o Code Optimization: It makes the code optimized, we can retrieve or sort


the data efficiently.
o Random access: We can get any data located at an index position.

Disadvantages

o Size Limit: We can store only the fixed size of elements in the array. It
doesn't grow its size at runtime. To solve this problem, collection framework
is used in Java which grows automatically.

Declaration and Initialization of Arrays :


In Java, declaring an array involves specifying the data type of the elements it will
hold, followed by square brackets [ ] and the array's name. This declaration
creates a reference variable, but no memory is allocated at this stage.

Syntax to Declare an Array in Java

dataType[] arrayRefVar; // Preferred way


dataType arrayRefVar[]; // Works but not preferred

Example:
int[ ] numbers; // Declares an array named 'numbers' to hold integers
String[ ] names; // Declares an array named 'names' to hold strings

Instantiation of an Array :(Array definition)

a) Using the new keyword:


This method allocates a fixed amount of memory for the array and optionally
initializes elements to their default values (e.g., 0 for numeric types, false for
booleans, null for reference types). Values can then be assigned to individual
elements using their index.
Syntax:

Example:

Example:
Initialization of an Array:
There are several ways to initialize an array in Java:
a) Using the new keyword (allocating memory and then assigning values):
This method first allocates a fixed amount of memory for the array and then
allows you to assign values to individual elements.
dataType[ ] arrayName = new dataType[size];
Example:
int[ ] numbers = new int[5]; // Declares and initializes an integer array of size 5
numbers[0] = 10;
numbers[1] = 20;
// ... and so on

B) Initialization at Declaration (using curly braces { }):


Arrays can be initialized during creation using an initializer list:
dataType[ ] arrayName = {value1, value2, ..., valueN};
Example:
int[ ] numbers = {1, 2, 3, 4, 5}; // Creates and initializes an array

Storage of Array in Computer Memory :


When an array is created, its elements are automatically initialized to default
values: 0 for numeric types, false for booleans, and null for reference types.
Default initial values in the array elements
 When an array is first created, every element contains an (default) initial
value.
 The initial value depends on the data type of the array elements.
 The initial value for each data type:

Accessing Elements of Arrays:


array elements are accessed using their index. The index represents the position
of the element within the array, and it is zero-based, meaning the first element is
at index 0, the second at index 1, and so on.
Syntax for Accessing an Element:
arrayName[index]
Example:
public class AccessArrayExample {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50};
// Accessing the first element (at index 0)
int firstElement = numbers[0];
// Accessing the third element (at index 2)
int thirdElement = numbers[2];
[Link]("First Element: " + firstElement);
[Link]("Third Element: " + thirdElement);
}
}
Operations on Array Elements :
Operations on array elements in Java involve various actions performed on the
data stored within an array. Common operations include:
 Accessing Elements:
Individual elements are accessed using their zero-based index.
int[ ] numbers = {10, 20, 30};
int firstElement = numbers[0]; // Accesses the element at index 0 (value 10)
 Modifying Elements:
Elements can be changed by assigning a new value to a specific index.
int[ ] numbers = {10, 20, 30};
numbers[1] = 25; // Modifies the element at index 1 to 25
 Traversing/Iterating:
All elements can be visited sequentially, typically using a for loop or an
enhanced for-each loop.

Assigning Array to Another Array :


assigning one array to another array variable performs a reference assignment,
not a deep copy of the array elements. This means both array variables will point
to the same underlying array object in memory.
Modifications made through one variable will be reflected when accessing through
the other.
Program:
class ArrayExample {
public static void main(String args[]) {
int[] sArray = { 1, 2, 3 };
int[] dArray = new int[[Link]];

dArray = sArray; // Array Assignment

for (int i = 0; i < [Link]; i++) {


[Link](“ “+dArray[i]);
}
sArray[2] = 10;

for (int i = 0; i < [Link]; i++) {


[Link](“ “+dArray[i]);
}
}
}
Output:
1 2 3
1 2 10
Dynamic Change of Array Size:
Java allows us to change the array size dynamically during the execution of the
program. In this process the array destroyed along with the values of elements. In
the following program, the array contains 5 elements. It is again defined with 10
elements with the same array name.
Example:
class Example {
public static void main(String args[]) {
int[] array1 = new int[] { 1, 2, 3, 4, 5 };
[Link]("Before Changing Array Size: \n\tarray1 = ");
display(array1);
// Changing array size
array1 = new int[10];

[Link]("\nAfter Changing Array Size:\n\tarray1 = ");


display(array1);
// adding values to the array elements
for (int i = 0; i < 10; i++)
array1[i] = 5 * (i + 1);

[Link]("\nAfter Modification :\n\tarray1 = ");


display(array1);
}
static void display(int[] array) // Method definition
{
for (int x : array)
[Link](x + " ");
}
}
Output:
Before Changing Array Size:
array1 = 1 2 3 4 5
After Changing Array Size:
array1 = 0 0 0 0 0 0 0 0 0 0
After Modification :
array1 = 5 10 15 20 25 30 35 40 45 50

Sorting of Arrays :
Sorting an array in Java without using the Arrays class typically involves
implementing a sorting algorithm manually. Several common algorithms can be
used for this purpose.
1. Bubble Sort:
This algorithm repeatedly steps through the list, compares adjacent elements, and
swaps them if they are in the wrong order. The pass through the list is repeated
until no swaps are needed, indicating that the list is sorted.
Bubble Sort Algorithm:
 Start at the beginning of the list.
 Compare each pair of adjacent elements.
 If the elements are in the wrong order, swap them.
 Move to the next pair and repeat step 3 until the end of the list.
 After each pass through the list, the largest element moves to its correct
position.
 Repeat the process for the remaining elements (excluding the last sorted
elements) until no swaps are needed.
First Pass

Example:
import [Link];

class BubbleDemo {
public static void main(String args[]) {
int n, i, j, temp;
int a[] = new int[20];
Scanner s = new Scanner([Link]);
[Link]("Enter total number of elements:");
n = [Link]();
[Link]("Enter elements:");
for (i = 0; i < n; i++)
a[i] = [Link]();
for (i = 0; i < n; i++) {
for (j = 0; j < n - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
[Link]("The sorted elements are:");
for (i = 0; i < n; i++)
[Link]("\t" + a[i]);
}
}

Output:
Enter total number of elements:
10
Enter elements:
12 34 1 5 7 3 8 2 11 6
The sorted elements are:
1 2 3 5 6 7 8 11 12 34

2. Insertion Sort:
Insertion sort is based on the idea of consuming one element from unsorted array
and inserting it at the correct position in the sorted array. This will result into
increasing the length of the sorted array by one and decreasing the length of
unsorted array by one after each iteration.

Example:
class InsertionSort
{
public static void main(String args[]) {
int[] a = new int[] { 5, 3, 4, 10, 1, 2, 8, 15 };
int n = [Link];
int temp, i, j;
[Link]("Before sorting of Array elements: ");
for (int x : a)
[Link](" " + x);

for (i = 1; i < n; i++) {


temp = a[i];
j = i - 1;
while (j >= 0 && a[j] > temp) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = temp;
}
[Link]("After Insertion sort");
for (i = 0; i < n; i++)
[Link](" " + a[i]);
}
}
Output:
Before sorting of Array elements:
5 3 4 10 1 2 8 15
After Insertion sort
1 2 3 4 5 8 10 15

3. Selection Sort:
Selection sort provides an improvement over bubble sort, with one swapping in
every pass. In every pass, it finds out the largest or the smallest element and puts
it in the right position. Consider that we have a sequence of integers.
First pass:
Program:
public class SelectionSort {
public static void selectionSort(int[] arr) {
int n = [Link];
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Swap the found minimum element with the first element
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
public static void main(String[] args) {
int[] numbers = { 5, 1, 4, 2, 8, 3, 10, 6, 12 };
[Link]("Before Sorted array:");
for (int num : numbers) {
[Link](num + " ");
}
selectionSort(numbers);
[Link]("\nSorted array (Selection Sort):");
for (int num : numbers) {
[Link](num + " ");
}
}
}

Output:
Before Sorted array:
5 1 4 2 8 3 10 6 12
Sorted array (Selection Sort):
1 2 3 4 5 6 8 10 12

Search for Values in Arrays:


There are several ways to search for values within an array, depending on
whether the array is sorted and the specific requirements of the search.
1. Linear Search:
This method involves iterating through each element of the array sequentially and
comparing it to the target value.
Program:
public class SearchEX {
public static void main(String[] a) {
int[] arr = new int[] { 23, 1, 4, 6, 9, 8, 13, 7 };
if (linearSearch(arr, 8))
[Link]("The element is found");
else
[Link]("The element isnot found");
}
public static boolean linearSearch(int[] arr, int target) {
for (int i = 0; i < [Link]; i++) {
if (arr[i] == target) {
return true; // Value found
}
}
return false; // Value not found
}
}
Output:
The element is found
2. Binary Search (for Sorted Arrays):
For sorted arrays, binary search is significantly more efficient than linear search. It
repeatedly divides the search interval in half.
Program:
public class BinarySearchEx {
public static int binarySearch(int arr[], int key) {
int low = 0;
int high = [Link] - 1;

while (low <= high) {


int mid = low + (high - low) / 2; // avoids overflow

if (arr[mid] == key) {
return mid; // found
}
if (arr[mid] < key) {
low = mid + 1; // search right half
} else {
high = mid - 1; // search left half
}
}
return -1; // not found
}

public static void main(String[] args) {


int[] arr = { 10, 20, 30, 40, 50, 60 };
int key = 40;

int result = binarySearch(arr, key);


if (result == -1)
[Link]("Element not found");
else
[Link]("Element found at index: " + result);
}
}

Output:
Element found at index:3

Class Arrays:
 The Arrays class is a utility class in the [Link] package.
 It provides static methods for working with arrays in Java.
 Since arrays are just data structures (not objects with methods), Arrays helps
perform common tasks like sorting, searching, comparing, filling, copying, and
converting arrays to strings.
 To use it, we need:
import [Link];

Key aspects of [Link]:


Static Methods:
All methods within the Arrays class are static, meaning they are invoked directly
on the class itself (e.g., [Link](myArray)), rather than on an instance of
the Arrays class.
Array Manipulation:
It provides methods for common array operations, including:
 Sorting: sort() methods for various primitive types and objects, including
parallel sorting.
 Searching: binarySearch() for efficiently searching sorted arrays.
 Comparing: equals() and deepEquals() for comparing array contents.
 Filling: fill() to assign a specific value to all elements of an array.
 Copying: copyOf() and copyOfRange() for creating copies of arrays or portions
of arrays.
 Converting to String: toString() and deepToString() for getting string
representations of arrays.
Utility Class:
It acts as a helpful toolkit for developers, simplifying array-related tasks that
would otherwise require manual implementation using loops or other constructs.
NullPointerException:
Most methods in this class will throw a NullPointerException if the provided array
reference is null.

Common Methods in Arrays Class

1. toString()
Converts the array into a human-readable string.
int arr[] = {10, 20, 30};
[Link]([Link](arr));
// Output: [10, 20, 30]

2. Sorting

import [Link];
public class ArraysExample {
public static void main(String[] args) {
int[] numbers = {50, 10, 30, 70, 20};

[Link](numbers); // Ascending order


[Link]("Sorted: " + [Link](numbers));
}
}
Output:
Sorted: [10, 20, 30, 50, 70]
👉 We can also sort part of an array:
int arr[] = {40, 30, 10, 20};
[Link](arr, 1, 3); // sorts index 1 to 2
[Link]([Link](arr));
// Output: [40, 10, 30, 20] → sorted sub-array [10,30]

3. Binary Search
Works only on sorted arrays.
int index = [Link](numbers, 30);
[Link]("Element found at index: " + index);
4. Fill Array
int[] arr = new int[5];
[Link](arr, 100); // Fill all elements with 100
[Link]([Link](arr));
Output:
[100, 100, 100, 100, 100]

5. Copy Array
 Copies an array into a new array.
 You can also change the length of the new array.
 If new length > old length → extra elements filled with default values (0,
false, null).
 If new length < old length → array gets truncated.

import [Link];

public class CopyOfExample {


public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};

int[] copy1 = [Link](arr, 3); // First 3 elements


int[] copy2 = [Link](arr, 7); // Extended to length 7

[Link]("Original: " + [Link](arr));


[Link]("copyOf (length 3): " + [Link](copy1));
[Link]("copyOf (length 7): " + [Link](copy2));
}
}
Output:
Original: [10, 20, 30, 40, 50]
copyOf (length 3): [10, 20, 30]
copyOf (length 7): [10, 20, 30, 40, 50, 0, 0]

copyOfRange
Copies a specific range from the original array.
Syntax:
[Link](original, from, to);
 from → starting index (inclusive).
 to → ending index (exclusive).
 If to > array length, extra elements filled with default values.
import [Link];

public class CopyOfRangeExample {


public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};

int[] sub1 = [Link](arr, 1, 4); // index 1 to 3


int[] sub2 = [Link](arr, 2, 7); // extends beyond
[Link]("Original: " + [Link](arr));
[Link]("copyOfRange(1,4): " + [Link](sub1));
[Link]("copyOfRange(2,7): " + [Link](sub2));
}
}

Output:
Original: [10, 20, 30, 40, 50]
copyOfRange(1,4): [20, 30, 40]
copyOfRange(2,7): [30, 40, 50, 0, 0]

6. Compare Arrays

int[] x = {1, 2, 3};


int[] y = {1, 2, 3};
[Link]([Link](x, y)); // true

Two Dimensional Array in Java:


A two-dimensional array in Java represents a collection of elements organized in
rows and columns, similar to a table or a matrix. It is essentially an array of
arrays.

Syntax to Declare Multidimensional Array in Java:

dataType[ ][ ] arrayRefVar; (or)


dataType [ ][ ]arrayRefVar; (or)
dataType arrayRefVar[ ][ ]; (or)
dataType [ ]arrayRefVar[ ];

Example
int[ ][ ] arr=new int[3][3];//3 row and 3 column

1. Separate Declaration and Instantiation

int[ ][ ] arr; // Declaration

arr = new int[2][2]; // Instantiation (2 rows, 2 columns)

2. Declaration + Instantiation (Memory Allocation)


int[ ][ ] arr = new int[2][3]; // 2 rows, 3 columns

3. Declaration + Instantiation + Initialization


int[ ][ ] arr = new int[ ][ ] { {1, 2, 3}, {4, 5, 6} };

// OR simply

int[ ][ ] arr = { {1, 2, 3}, {4, 5, 6} };

Example:
Let's see the simple example to declare, instantiate, initialize and print the
2Dimensional array.
//Java Program to illustrate the use of multidimensional array
class Testarray1{
public static void main(String args[]){
//declaring and initializing 2D array
int arr[ ][ ]={{1,2,3},{2,4,5},{4,4,5}};
//printing 2D array
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
[Link](arr[i][j]+" ");
}
[Link]();
}
}}
Output:
1 2 3
2 4 5
4 4 5

Example: Addition of two matrices:

import [Link].*;

class ArraysEx {
public static void main(String args[]) {
Scanner sc = new Scanner([Link]);
int [ ] arr[ ] = new int[2][2];
int[ ][ ] brr = { { 11, 12 }, { 13, 14 } };
int c[ ][ ] = new int[2][2];
int i = 0, j;
//for each
[Link]("Enter the elements for arr array:");
for (int[ ] x : arr) {
j = 0;
for (int y : x) {
arr[i][j] = [Link]();
j++;
}
i++;
}

[Link]("arr is: " + [Link](arr));


[Link]("brr is: " + [Link](brr));

for (i = 0; i < [Link]; i++) {


for (j = 0; j < arr[i].length; j++) {
c[i][j] = arr[i][j] + brr[i][j];
}
}
[Link]("Addition of two arrays is: " +
[Link](c));
}
}

Output:
Enter the elements for arr array:
6484
arr is: [[6, 4], [8, 4]]
brr is: [[11, 12], [13, 14]]
addition of two arrays is: [[17, 16], [21, 18]]

Arrays of Varying Lengths:


In Java, arrays of varying lengths are known as jagged arrays or ragged
arrays. Unlike traditional rectangular multidimensional arrays where each row (or
dimension) has the same number of elements, jagged arrays allow each inner
array to have a different length. This provides flexibility when dealing with data
that doesn't fit into a uniform, fixed-size structure.

How to create and use jagged arrays in Java:


Declaration:
Declare a two-dimensional array, but only specify the size of the first dimension
(the number of inner arrays). The second dimension is left empty.
int[][] jaggedArray = new int[3][]; // Declares an array of 3 integer arrays
Initialization of Inner Arrays:
Initialize each inner array separately with its desired length.
jaggedArray[0] = new int[5]; // First inner array has a length of 5
jaggedArray[1] = new int[2]; // Second inner array has a length of 2
jaggedArray[2] = new int[7]; // Third inner array has a length of 7
Accessing Elements:
Access elements using nested loops, iterating through the outer array and then
through each inner array based on its specific length.
for (int i = 0; i < [Link]; i++) {
for (int j = 0; j < jaggedArray[i].length; j++) {
// Access or modify jaggedArray[i][j]
}
}
Example:
public class JaggedArrayExample {
public static void main(String[] args) {
// Declare a jagged array
int[][] numbers = new int[3][];

// Initialize inner arrays with varying lengths


numbers[0] = new int[ ]{1, 2, 3};
numbers[1] = new int[ ]{4, 5};
numbers[2] = new int[ ]{6, 7, 8, 9};
// Print the elements of the jagged array
for (int i = 0; i < [Link]; i++) {
[Link]("Row " + i + ": ");
for (int j = 0; j < numbers[i].length; j++) {
[Link](numbers[i][j] + " ");
}
[Link]();
}
}
}
Three-dimensional Arrays :
A 3D array in Java is an array of arrays of arrays.
It is a collection of elements arranged in three dimensions:
 The first dimension represents layers (or planes).
 The second dimension represents rows.
 The third dimension represents columns.
We can think of it as a cube of data (a stack of 2D arrays).

Syntax:
dataType[ ][ ][ ] arrayName = new dataType[size1][size2][size3];
 size1 → number of 2D matrices (layers)
 size2 → number of rows in each matrix
 size3 → number of columns in each matrix
Example:
int[ ][ ][ ] arr = new int[2][3][4];
 2 layers (first dimension)
 Each layer has 3 rows (second dimension)
 Each row has 4 columns (third dimension)
So, total elements = 2 × 3 × 4 = 24.

Declaration and Initialization:

A 3D array in Java is declared using three sets of square brackets [ ][ ][ ] after the
data type.

dataType[ ][ ][ ] arrayName;

For example, to declare a 3D array of integers:

int[ ][ ][ ] intArray;

To initialize a 3D array with a specific size, we use the new keyword, specifying
the size of each dimension:

int[ ][ ][ ] matrix = new int[2][3][4]; // Creates a 3D array with 2 "tables", 3 "rows",


and 4 "columns"

We can also initialize a 3D array directly with values at the time of declaration:

int[][][] data = {
{{1, 2, 3}, {4, 5, 6}},
{{7, 8, 9}, {10, 11, 12}}
};

Accessing Elements:

Elements in a 3D array are accessed using three indices, corresponding to the


"table," "row," and "column" position.

int value = matrix[0][1][2]; // Accesses the element at table 0, row 1, column 2

Example:
public class ThreeDArrayExample {
public static void main(String[] args) {
// Declare and initialize a 3D array
int[ ][ ][ ] arr = {
{ {1, 2, 3}, {4, 5, 6} }, // Layer 0
{ {7, 8, 9}, {10, 11, 12} } // Layer 1
};
// Printing elements of the 3D array
for (int i = 0; i < [Link]; i++) { // First dimension (layers)
[Link]("Layer " + i + ":");
for (int j = 0; j < arr[i].length; j++) { // Second dimension (rows)
for (int k = 0; k < arr[i][j].length; k++) { // Third dimension (columns)
[Link](arr[i][j][k] + " ");
}
[Link]();
}
[Link]();
}
}
}
(or)
For each:
int layerIndex = 0;
for (int[ ][ ] x : arr) { // First dimension (layers)
[Link]("Layer " + layerIndex + ":");
for (int[ ] y : x) { // Second dimension (rows)
for (int z : y) { // Third dimension (columns)
[Link](z + " ");
}
[Link]();
}
[Link]();
layerIndex++;
}
Output:
Layer 0:
123
456

Layer 1:
789
10 11 12
Arrays as Vectors:
Similar to Arrays, vectors are another kind of data structure that is used for
storing information. Using vectors, we can implement a dynamic array. As we
know, an array can be declared in the following way:
int marks[] = new int[7];
A Vector in Java is a dynamic array that can grow or shrink in size automatically
as elements are added or removed.
 It is a class in the [Link] package.
 Unlike arrays, its size is not fixed.
 It can store objects of any type (e.g., Integer, Float, String).
 Vectors are synchronized, which means they are safe for use in multithreaded
programs.
Constructors of Vector
 Vector() → creates a vector with default capacity 10.
Vector v = new Vector();
 Vector(int size) → creates a vector with given initial capacity.
Vector v = new Vector(5);
 Vector(int size, int incr) → creates a vector with given initial capacity and
capacity increment.
Vector v = new Vector(5, 2); // size=5, grows by +2 when needed
 Vector(Collection c) → creates a vector containing elements of collection c.

Important Methods of Vector:

Method Use
void add(int index, Object
Insert element at given position
element)
void addElement(Object obj) Add element at end
void clear() Remove all elements
int capacity() Returns current capacity
void copyInto(Object[] anArray) Copy elements into an array
Object firstElement() Returns first element
Object lastElement() Returns last element
Enumeration elements() Returns an Enumeration of elements
Object get(int index) Get element at index
Object remove(int index) Remove element at index
int size() Number of elements in vector
Example Program – Vector Operations
import [Link].*;
public class VectorList {
public static void main(String args[]) {
Vector<Number> vec = new Vector<>(5, 2); // initial size 5, increment 2
[Link]("Initial size: " + [Link]());
[Link]("Initial capacity: " + [Link]());
[Link](17);
[Link](10);
[Link](3);
[Link](5.6f);
[Link](10.8f);
[Link](23);
[Link]("Enhanced capacity after addition: " + [Link]());
[Link](55);
[Link]("Current capacity is: " + [Link]());
// ✅ Display elements
[Link]("Elements in vector:");
for (Object element : vec) {
[Link](element);
}
}
}
Output:
Initial size: 0
Initial capacity: 5
Enhanced capacity after addition: 7
Current capacity is: 7
Elements in vector:
17
10
3
5.6
10.8
23
55
Note:
Vector<Number> vec = new Vector<>(5, 2);
That only accepts subclasses of Number (like Integer, Float, Double).
So if you try [Link]("Hello"), it will give a compile-time error ❌.
1. Use Vector<Object>
Vector<Object> vec = new Vector<>(5, 2);
[Link](17); // Integer
[Link](5.6f); // Float
[Link]("Hello"); // String
[Link](true); // Boolean

 This works because everything in Java is an Object.


2. Use Vector<String> (only strings allowed)
Vector<String> vec = new Vector<>(5, 2);
[Link]("Apple");
[Link]("Banana");
[Link]("Cherry");

 This restricts to Strings only.


3. For Characters:
Vector<Character> vec = new Vector<>(5, 2);
[Link]('A');
[Link]('B');
[Link]('C');
[Link]('D');
[Link]('E');
Example:
import [Link].*;

public class VectorExample {


public static void main(String[] args) {
// 1. Create a vector with initial capacity 3 and increment 2
Vector<Object> vec = new Vector<>(3, 2);

// 2. Add elements
[Link](10); // add(Object)
[Link](20);
[Link](30); // addElement(Object)
[Link](1, 15); // add at index

// 3. Display elements
[Link]("Vector elements: " + vec);

// 4. Size and capacity


[Link]("Size: " + [Link]());
[Link]("Capacity: " + [Link]());

// 5. Access first and last elements


[Link]("First element: " + [Link]());
[Link]("Last element: " + [Link]());

// 6. Get element at index


[Link]("Element at index 2: " + [Link](2));

// 7. Remove element at index


[Link](1);
[Link]("After removing index 1: " + vec);

// 8. Copy into array


Object[] arr = new Object[[Link]()];
[Link](arr);
[Link]("Copied into array: " + [Link](arr));

// 9. Iterate using Enumeration


[Link]("Iterating with Enumeration:");
Enumeration<Object> e = [Link]();
while ([Link]()) {
[Link]([Link]() + " ");
}
[Link]();

// 10. Clear vector


[Link]();
[Link]("After clear, size: " + [Link]());
}
}
Output:
Vector elements: [10, 15, 20, 30]
Size: 4
Capacity: 5
First element: 10
Last element: 30
Element at index 2: 20
After removing index 1: [10, 20, 30]
Copied into array: [10, 20, 30]
Iterating with Enumeration:
10 20 30
After clear, size: 0

Difference between Array and Vector in Java


Feature Array Vector
A fixed-size data structure A dynamic array (class in [Link])
Definition that stores elements of the that can grow or shrink in size
same type. automatically.
Fixed at the time of creation Increases automatically when more
Size
and cannot be changed. elements are added.
Type of Can store primitive types Stores only objects (primitives are
Elements (int, char, etc.) and objects. auto-boxed, e.g., int → Integer).
Not flexible — once size is Very flexible — grows/shrinks as
Flexibility
defined, it cannot grow. needed.
Not synchronized (not thread- Synchronized (thread-safe, but
Synchronized
safe). slower compared to ArrayList).
Faster, as no synchronization Slightly slower due to
Performance
overhead. synchronization.
Package Built into Java language. Belongs to [Link] package.
Best when size is known in Best when dynamic resizing is
Usage advance and performance needed and thread safety is
matters. important.
Inheritance:
Introduction:
Inheritance in Java is a fundamental concept of Object-Oriented Programming
(OOP) that allows a class to acquire the properties and behaviors (fields and
methods) of another class. This mechanism promotes code reusability and
establishes a hierarchical relationship between classes.
Key Concepts:
Superclass (Parent Class / Base Class): The class whose properties and
behaviors are inherited.
Subclass (Child Class / Derived Class): The class that inherits properties and
behaviors from the superclass.
extends Keyword: Used in Java to implement inheritance, indicating that a class
is inheriting from another.
How it Works:
When a subclass extends a superclass, it gains access to the superclass's non-
private fields and methods. This means the subclass can reuse the functionality
defined in the superclass without rewriting the code. The subclass can also add its
own unique fields and methods, or override inherited methods to provide specific
implementations.
Example:
class Animal {
String name;
void eat() {
[Link](name + " is eating.");
}
}
class Dog extends Animal { // Dog inherits from Animal
void bark() {
[Link](name + " is barking.");
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
[Link] = "Buddy"; // Inherited from Animal
[Link](); // Inherited from Animal
[Link](); // Specific to Dog
}
}
Output:
Buddy is eating.
Buddy is barking.
Process of Inheritance:
Declaration: A subclass is declared using the extends keyword, followed by the
name of the superclass.
Syntax:
class Superclass {
// fields and methods of the superclass
}
class Subclass extends Superclass {
// fields and methods of the subclass
}
Inheritance of Members:
 The subclass automatically inherits all non-private fields and methods from its
superclass.
 Private members of the superclass are not directly accessible in the subclass,
but they can be accessed indirectly through public or protected methods
provided in the superclass.
Constructors:
 Constructors are not inherited.
 A subclass's constructor implicitly or explicitly calls a constructor of its
superclass using the super() keyword. super() must be the first statement in
the subclass constructor.
 If no explicit super() call is made, the default no-argument constructor of the
superclass is implicitly called.
Types of Inheritances :
The different 5 types of Inheritance in java are:
1. Single inheritance.
2. Multi-level inheritance.
3. Hierarchical Inheritance.
4. Multiple inheritance.
5. Hybrid Inheritance.

Note: Multiple inheritance is not supported in Java through class.

Single Inheritance:
Single inheritance is a type of inheritance where a class (the subclass or child
class) inherits properties and behaviors from only one other class (the superclass
or parent class). It is the simplest and most fundamental form of inheritance in
Java.
Example:
class A
{
int a, b;
void display()
{
[Link](“Inside class A values =”+a+” ”+b);
}
}
class B extends A
{
int c;
void show()
{
[Link](“Inside Class B values=”+a+” “+b+” “+c);
}
Output:
Inside class A values =10 20
Inside Class B values=10 20 30
}
class SingleInheritance
{
public static void main(String args[])
{
B obj = new B(); //derived class object
obj.a=10;
obj.b=20;
obj.c=30;
[Link]();
[Link]();
}
}
Multi-level inheritance:
Multilevel inheritance in Java is a type of inheritance where a class inherits from a
parent class, which in turn inherits from another class, forming a chain or
hierarchy of inheritance. This means that a class can act as both a subclass
(inheriting from another class) and a superclass (being inherited by another
class).

Syntax
class A {
// Parent class (Grandparent)
}
class B extends A {
// Child class of A (Parent)
}
class C extends B {
// Child class of B (Grandchild of A)
}
Example:
class GrandParent {
void displayGrandParent() {
[Link]("This is the GrandParent class.");
}
}
class Parent extends GrandParent {
void displayParent() {
[Link]("This is the Parent class.");
}
}
class Child extends Parent {
void displayChild() {
[Link]("This is the Child class.");
}
}
public class MultilevelInheritanceExample {
public static void main(String[] args) {
Child childObj = new Child();
[Link](); // Inherited from GrandParent
[Link](); // Inherited from Parent
[Link](); // Defined in Child
}
}
Output:
This is the GrandParent class.
This is the Parent class.
This is the Child class.
Another Example:
class Person {
String name;
int age;
void setPerDetails(String n, int a) {
name = n;
age = a;
}
void displayPerDetails() {
[Link]("Name: " + name);
[Link]("Age: " + age);
}
}
// Parent class
class Employee extends Person {
int empId;
double salary;
void setEmpDetails(int id, double sal) {
empId = id;
salary = sal;
}
void displayEmpDetails() {
[Link]("Employee ID: " + empId);
[Link]("Salary: " + salary);
}
}
// Child class
class Manager extends Employee {
String department;
void setMngDetails(String dept) {
department = dept;
}
void displayMngDetails() {
[Link]("Department: " + department);
}
}
// Main class
public class MultilevelInheritanceWithVariables {
public static void main(String[] args) {
Manager m = new Manager();
// Setting values for all levels
[Link]("Alice", 35); // from Person
[Link](101, 75000.50); // from Employee
[Link]("Computer Science"); // from Manager
// Displaying values
[Link]();
[Link]();
[Link]();
}
}
Output:
Name: Alice
Age: 35
Employee ID: 101
Salary: 75000.5
Department: Computer Science
Hierarchical Inheritance:
Hierarchical inheritance in Java is a type of inheritance where multiple subclasses
inherit from a single superclass. This creates a tree-like structure where the
superclass forms the base, and several specialized subclasses extend it.

Example:
// Superclass
class Vehicle {
void run() {
[Link]("Vehicles can run");
}
}
// Subclass 1
class Car extends Vehicle {
void displayCar() {
[Link]("Car is a four-wheeler");
}
}

// Subclass 2
class Bike extends Vehicle {
void displayBike() {
[Link]("Bike is a two-wheeler");
}
}
// Subclass 3
class Truck extends Vehicle {
void displayTruck() {
[Link]("Truck is used to carry heavy loads");
}
}
public class HierarchicalInheritanceExample {
public static void main(String[] args) {
Car c = new Car();
Bike b = new Bike();
Truck t = new Truck();
// Accessing common method from Vehicle
[Link]();
[Link]();
[Link]();
// Accessing individual methods
[Link]();
[Link]();
[Link]();
}
}
Output:
Vehicles can run
Vehicles can run
Vehicles can run
Car is a four-wheeler
Bike is a two-wheeler
Truck is used to carry heavy loads

Multiple inheritance in java:


Java does not support multiple inheritance of classes directly. This means a class
cannot extend more than one parent class using the extends keyword. This design
choice was made to avoid complexities and ambiguities, such as the "Diamond
Problem," where a class might inherit conflicting method implementations from
multiple parent classes.
However, Java achieves a form of multiple inheritance through interfaces. A class
can implement multiple interfaces, thereby inheriting the abstract methods
defined in those interfaces. The implementing class is then responsible for
providing the concrete implementation for all inherited abstract methods.
Example:
// First interface
interface InterfaceA {
void methodA();
}
// Second interface
interface InterfaceB {
void methodB();
}
// Class implementing both interfaces
class MyClass implements InterfaceA, InterfaceB {
public void methodA() {
[Link]("Method A from InterfaceA");
}
public void methodB() {
[Link]("Method B from InterfaceB");
}
}
public class MultipleInheritanceExample {
public static void main(String[] args) {
MyClass obj = new MyClass();
[Link]();
[Link]();
}
}

Output:
Method A from InterfaceA
Method B from InterfaceB
Another Example:
// First interface
interface InterfaceA {
int a = 10; // by default: public, static, final
void methodA();
}
// Second interface
interface InterfaceB {
int b = 20; // by default: public, static, final
void methodB();
}
// Class implementing both interfaces
class MyClass implements InterfaceA, InterfaceB {
public void methodA() {
[Link]("Value of a (from InterfaceA): " + a);
}
public void methodB() {
[Link]("Value of b (from InterfaceB): " + b);
}
void sum() {
[Link]("Sum of a and b: " + (a + b));
}
}
public class MultipleInheritanceWithVariables {
public static void main(String[] args) {
MyClass obj = new MyClass();
[Link](); // Access InterfaceA variable
[Link](); // Access InterfaceB variable
[Link](); // Using both variables together
}
}

Output:
Value of a (from InterfaceA): 10
Value of b (from InterfaceB): 20
Sum of a and b: 30
Key Points
 Variables in interfaces are implicitly public, static, and final → like constants.
 They must be initialized in the interface itself.
 The implementing class can use them directly but cannot change their values.
Hybrid Inheritance:
Hybrid inheritance in Java refers to a combination of two or more types of
inheritance within a single class hierarchy. While Java does not support multiple
inheritance directly through classes (to avoid issues like the Diamond Problem),
hybrid inheritance is achieved through a combination of class inheritance and
interface implementation.
Example:
// Parent class
class Person {
void speak() {
[Link]("Person can speak");
}
}
// Interface 1
interface Learner {
void study();
}
// Interface 2
interface Worker {
void work();
}
// Child class (inherits class + implements interfaces)
class Student extends Person implements Learner, Worker {
@Override
public void study() {
[Link]("Student is studying");
}

@Override
public void work() {
[Link]("Student is also working part-time");
}
}
public class HybridAnotherExample {
public static void main(String[] args) {
Student s = new Student();
[Link](); // from Person
[Link](); // from Learner
[Link](); // from Worker
}
}
Output:
Person can speak
Student is studying
Student is also working part-time
Diamond Problem Example:

interface Parent1 {
default void commonMethod() {
[Link]("Parent1's common method");
}
}
interface Parent2 {
default void commonMethod() {
[Link]("Parent2's common method");
}
}
// Child inherits both interfaces
class Child implements Parent1, Parent2 {
@Override
public void commonMethod() {
// Must resolve ambiguity explicitly
[Link]("Child resolves the diamond problem");
// Optionally call one parent's method:
[Link]();
[Link]();
}
}
public class DiamondProblemExample {
public static void main(String[] args) {
Child c = new Child();
[Link]();
}
}
Output:
Child resolves the diamond problem
Parent1's common method
Parent2's common method
Universal Super Class-Object Class :
In Java, the Object class, found in the [Link] package, serves as the universal
superclass for all other classes. This means that every class in Java, whether it is a
built-in class like String or a user-defined class, implicitly or explicitly inherits from
the Object class.

Inheritance of Common Methods:


All classes in Java inherit a set of fundamental methods from
the Object class. These methods provide basic functionalities common to all
objects, such
as equals(), hashCode(), toString(), clone(), getClass(), notify(), notifyAll(),
and wait().

Method Description

public final Class getClass() returns the Class class object of this
object. The Class class can further be used
to get the metadata of this class.

public int hashCode() returns the hashcode number for this


object.

public boolean equals(Object obj) compares the given object to this object.

protected Object clone() throws creates and returns the exact copy (clone)
CloneNotSupportedException of this object.

public String toString() returns the string representation of this


object.

public final void notify() wakes up single thread, waiting on this


object's monitor.

public final void notifyAll() wakes up all the threads, waiting on this
object's monitor.

public final void wait(long causes the current thread to wait for the
timeout)throws specified milliseconds, until another thread
InterruptedException notifies (invokes notify() or notifyAll()
method).
public final void wait(long causes the current thread to wait for the
timeout,int nanos)throws specified milliseconds and nanoseconds,
InterruptedException until another thread notifies (invokes
notify() or notifyAll() method).

public final void wait()throws causes the current thread to wait, until
InterruptedException another thread notifies (invokes notify() or
notifyAll() method).

protected void finalize()throws is invoked by the garbage collector before


Throwable object is being garbage collected.

1. toString() method
The toString() provides a String representation of an object and is used to
convert an object to a String. The default toString() method for class Object
returns a string consisting of the name of the class of which the object is an
instance, the at-sign character `@’, and the unsigned hexadecimal
representation of the hash code of the object. In other words, it is defined as:

// Default behavior of toString() is to print class name, then

// @, then unsigned hexadecimal representation of the hash code

// of the object

public String toString()

return getClass().getName() + "@" + [Link](hashCode());

It is always recommended to override the toString() method to get our own


String representation of Object.
Note: Whenever we try to print any Object reference, then internally toString()
method is called.
Student s = new Student();

// Below two statements are equivalent

[Link](s);

[Link]([Link]());
2. hashcode():

It returns a hash value that is used to search objects in a collection. JVM(Java


Virtual Machine) uses the hashcode method while saving objects into hashing-
related data structures like HashSet, HashMap, Hashtable, etc. The main
advantage of saving objects based on hash code is that searching becomes
easy.

Note: Override of hashCode() method needs to be done such that for every
object we generate a unique number. For example, for a Student class, we can
return the roll no. of a student from the hashCode() method as it is unique.
Example:
// Java program to demonstrate working of
// hashCode() and toString()
public class Student {
static int last_roll = 100;
int roll_no;
// Constructor
Student()
{
roll_no = last_roll;
last_roll++;
}
Output:
// Overriding hashCode() Student@64
Student@64
public int hashCode() { return roll_no; }
// Driver code
public static void main(String args[])
{
Student s = new Student();
// Below two statements are equivalent
[Link](s);
[Link]([Link]());
}
}
3. equals():
This method compares two objects and returns whether they are equal or not. It
is used to compare the value of the object on which the method is called and the
object value which is passed as the parameter.
4. getClass():
It is used to return the class object of this object. Also, it fetches the actual
runtime class of the object on which the method is called. This is also a native
method. It can be used to get the metadata of the this class. Metadata of a
class includes the class name, fields name, methods, constructor, etc.
Example:
Output:
public class MainClass { Class of Object s is : [Link]
public static void main(String[] args) { Class of Object i is : [Link]
Object s = new String("Hi");
Object i = new Integer(19);
Class c = [Link]();
Class d = [Link]();
// for the String
[Link]("Class of Object s is : " + [Link]());
// for the integer
[Link]("Class of Object i is : " + [Link]());
}
}
5. clone():
The clone() method is used to create an exact copy of this object. It creates a
new object and copies all the data of the this object to the new object.
Example:
import [Link].*;
class MainClass implements Cloneable {
// declare variables
String name;
int age;
public static void main(String[] args) {
// create an object of Main class
MainClass obj1 = new MainClass();
// initialize name and age using obj1
[Link] = "xyz"; Output:
[Link] = 19; xyz 19
xyz 19
// print variable
[Link]([Link]); // xyz
[Link](" " + [Link]); // 19
try {
// create clone of obj1
MainClass obj2 = (MainClass) [Link]();
// print the variables using obj2
[Link]([Link]); // xyz
[Link](" " + [Link]); // 19
} catch (Exception e) {
[Link](e);
}
}
}
final key word:
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

final Variable – Once a variable is declared as final, it can be initialized during


declaration or in the constructor. And can never be changed during the course of
the program. Hence static final variables are also called constants.
If we make any variable as final, we cannot change the value of final variable(It
will be constant).
Example:
public class Audi {
public final String EngineNumber;
public Audi(String EngineNumber){
[Link] = EngineNumber;
}
public static void main(String[] args) {
Audi audi = new Audi("ABCD1234");
[Link] = "CDEF4568";
[Link]("Engine Number : "+[Link]);
}
}
Java Compiler throws an Error

The final field [Link] cannot be assigned.

final Method – Once a method is declared as final, it can never be overridden by


any sub class that is inheriting the method’s class.
Example:
public class Car {
public void brake(){
[Link]("break in Car");
}
public final void accelerate(){
[Link]("accelerate in Car");
}
}
public class Audi extends Car {
public static void main(String[] args)
{
Audi audi = new Audi();
[Link]();
[Link]();
}
public void accelerate(){
[Link]("accelerate in Audi");
}
}
Java Compilation Error occurs

Cannot override the final method from Car

final Class – Once a class is declared as final, it can never be inherited.


Example:
final class Bike{ }
class Honda1 extends Bike{
void run(){[Link]("running safely with 100kmph");}
public static void main(String args[]){
Honda1 honda= new Honda1();
[Link]();
}
}
Java Compiler throws an Error

Cannot inherited the final class Bike

Relation Between Access Control and Inheritance


 Private members of parent → not inherited (only accessible within parent).
 Default members → inherited only within same package.

 Protected members → inherited in subclass (even if subclass is in another


package).

 Public members → always inherited.

Super Keyword:
The super keyword in Java is a reference variable which is used to refer
immediate parent class object.
Whenever we create the instance of subclass, an instance of parent class is
created implicitly which is referred by super reference variable.

Usage of Java super Keyword


1. super can be used to refer immediate parent class instance variable.
2. super can be used to invoke immediate parent class method.
3. super() can be used to invoke immediate parent class constructor.
1) super can be used to refer immediate parent class instance
variable.
We can use super keyword to access the data member or field of parent class. It is
used if parent class and child class have same fields.
class Animal{
String color="white";
Output:
} black
class Dog extends Animal{ white
String color="black";
void printColor(){
[Link](color);//prints color of Dog class
[Link]([Link]);//prints color of Animal class
}
}
class TestSuper1{
public static void main(String args[]){
Dog d=new Dog();
[Link]();
}}
In the above example, Animal and Dog both classes have a common
property color. If we print color property, it will print the color of current class by
default. To access the parent property, we need to use super keyword.
2) super can be used to invoke parent class method
The super keyword can also be used to invoke parent class method. It should be
used if subclass contains the same method as parent class. In other words, it is
used if method is overridden
// Java code to show use of super keyword with variables
// Base class vehicle
class Vehicle {
int maxSpeed = 120;
void display() {
// print maxSpeed of base class (vehicle)
[Link]("vehicle class display");
Output:
} vehicle class display
car class display
Maximum Speed: 120
}
// sub class Car extending vehicle
class Car extends Vehicle {
int maxSpeed = 180;
void display() {
// print maxSpeed of base class (vehicle)
[Link]();
[Link]("car class display");
[Link]("Maximum Speed: " + [Link]);
}
}
// Driver Program
class Test {
public static void main(String[] args) {
Car small = new Car();
[Link]();
}
}
3) super is used to invoke parent class constructor.
The super keyword can also be used to invoke the parent class constructor.
class A
{
int a;
A(int a)
{
this.a=a;
[Link]("a="+a);
}
}
class B extends A
{
int b;
B(int a,int b)
{
super(a);
[Link]("b="+b);
}
}
class TestSuper
{
public static void main(String args[])
{
B obj=new B(4,5);
}
}
Output:
a=4
b=5
Note:
Even though a subclass includes all of the members of its super class, it cannot
access those members who are declared as Private in super class.
Multilevel Inheritance:
In simple inheritance a subclass or derived class derives the properties from its
parent class, but in multilevel inheritance a subclass is derived from a derived
class. One class inherits only single class. Therefore, in multilevel inheritance,
every time ladder increases by one. The lower most class will have the properties
of all the super classes’
It is common that a class is derived from another derived class. The class student
serves as a base class for the derived class marks, which in turn serves as a base
class for the derived class percentage. The class marks is known as intermediates
base class since it provides a link for the inheritance
between student and percentage. The chain is known as
inheritance path. When this type of situation occurs,
each subclass inherits all of the features found in all of its
super classes. In this case, percentage inherits all
aspects of marks and student.
Example:
class student {
int rollno;
String name;
student(int r, String n) {
rollno = r;
name = n;
}
void dispdatas() {
[Link]("Rollno = " + rollno);
[Link]("Name = " + name);
}
}
class marks extends student {
int total;
marks(int r, String n, int t) {
super(r, n); // call super class (student) constructor
total = t;
}
void dispdatam() {
dispdatas(); // call dispdatap of student class
Output:
[Link]("Total = " + total); B class object
} method of Class A
method of Class B
} C class object
class percentage extends marks { method of Class A
method of Class C
int per; D class object
percentage(int r, String n, int t, int p) { method of Class A
method of Class D
super(r, n, t); // call super class(marks) constructor A class object
per = p; method of Class A

}
void dispdatap() {
dispdatam(); // call dispdatap of marks class
[Link]("Percentage = " + per);
}
}
class Multi_Inhe {
public static void main(String args[]) {
percentage stu = new percentage(102689, "RATHEESH", 350, 70); // call
constructor percentage
[Link](); // call dispdatap of percentage class
} }
Output:
Rollno = 102689
Name = RATHEESH
Total = 350
Percentage = 70
Hierarchical Inheritance:
In Hierarchical Inheritance, one class serves as a superclass (base class) for more
than one sub class. In other words the process of deriving multiple subclasses
from the same superclass is known as Hierarchical inheritance.
Example:
class A {
public void methodA() {
[Link]("method of Class A");
}
}
class B extends A {
public void methodB() {
[Link]("method of Class B");
}
}
class C extends A {
public void methodC()
{
[Link]("method of Class C");
}
}
class D extends A {
public void methodD() {
[Link]("method of Class D");
}
}
class JavaExample {
public static void main(String args[]) {
B obj1 = new B();
C obj2 = new C();
D obj3 = new D();
[Link]("B class object");
[Link]();
[Link]();
[Link]("C class object");
[Link]();
[Link]();
[Link]("D class object");
[Link]();
[Link]();
[Link]("A class object");
A obj4 = new A();
[Link]();
}
}
Another Example:
// Superclass
class College {
String name;
int id;
static String collegeName = "RGM College"; // common for all
// Constructor
College(String name, int id) {
[Link] = name;
[Link] = id;
}
// Display method
void display() {
[Link]("Name: " + name);
[Link]("ID: " + id);
}
}
// Subclass 1: Student
class Student extends College {
int marks;
Student(String name, int id, int marks) {
super(name, id); // call College constructor
[Link] = marks;
}
void display() {
[Link](); // call College display()
[Link]("Marks: " + marks);
[Link]("---------------------");
}
}
// Subclass 2: Faculty
class Faculty extends College {
String subject;
Faculty(String name, int id, String subject) {
super(name, id);
[Link] = subject;
}
void display() {
[Link]();
[Link]("Subject: " + subject);
[Link]("---------------------");
}
}
// Subclass 3: Staff
class Staff extends College {
String designation;
Staff(String name, int id, String designation) {
super(name, id);
[Link] = designation;
}
void display() {
[Link]();
[Link]("Designation: " + designation);
[Link]("---------------------");
}
}
// Main class
public class HierarchicalInheritanceDemo {
public static void main(String[] args) {
// Print college name only once
[Link]("College Name: " + [Link]);
[Link]("=====================");
// Create objects
Student s = new Student("Rahul", 101, 85);
Faculty f = new Faculty("Meena", 201, "Computer Science");
Staff st = new Staff("Suresh", 301, "Clerk");
// Display details
[Link]();
[Link]();
[Link]();
}
}
Output:
College Name: RGM College
=====================
Name: Rahul
ID: 101
Marks: 85
---------------------
Name: Meena
ID: 201
Subject: Computer Science
---------------------
Name: Suresh
ID: 301
Designation: Clerk
---------------------
Polymorphism:
Ability of an object to take many forms.
An object in java that passes IS-A test polymorphic and since all objects
extends Object class hence all objects are polymorphic.
Polymorphism is two types:
1. Compile time polymorphism (static polymorphism)
2. Run time polymorphism (dynamic polymorphism / dynamic method dispatch /
virtual method invocation).
Note:
Overloading is not possible by changing the return type only. It gives compile time
error due to ambiguity.

Compiletime Polymorphism

Method overloading allows a class to have multiple methods with the same name
but different parameter lists. This is an example of compile-time polymorphism,
where the method call is resolved during compilation based on the arguments
passed. It improves code readability and reusability by enabling method
customization for different inputs without requiring unique method names.
Rules Of Method Overloading In Java
1. The method name must be the same.
2. The parameter list must differ (by number, type, or order).
3. The return type may or may not be the same.
4. It is independent of access modifiers.
5. Static methods can be overloaded.

Case 1: Automatic type promotion concept:(Match format)


public class TypePro {
void add(double a, int b) {
[Link]("double,int-arg = " + (a + b));
}
void add(int a, int b) {
[Link]("int-arg = " + (a + b));
}
public static void main(String[] args) {
TypePro t = new TypePro();
[Link](2, 3); // Exact match is found because 2,3 are an integer data types.
So, //output is int-arg.
[Link](1.5f, 8); // Exact match is found because 1.5f,8 are an float,int data
//types. So, output is double,int-arg.
}
}

Output:

int-arg = 5
double,int-arg = 9.5

Case 2: Does not Match but can be promoted the call


public class TypePro {
public void add(double a) {
[Link](a + a);
}
public void add(float a) {
[Link](a + a);
}
public static void main(String[] args) {
TypePro t = new TypePro();
[Link](2); // Exact match is not found for passing argument 2 because 2 is an
integer data type.
}
}

Output:

4.0
Explanation:
1. When an exact match is not found for passing argument then the compiler finds
the method with the smallest argument.
2. In the above example, float and double both belong to float category data type.
Due to which an exact match is not found for passing argument 2 because 2 is an
integer data type.
Therefore, the compiler finds the method with the smallest argument float rather
than double. The float data type is a smaller size than double and consumes less
memory.

Case 3:
class OverloadDemo {

void add(int a, long b) {


[Link]("add(int,long) called");
}

void add(long a, int b) {


[Link]("add(long,int) called");
}
public static void main(String[] args) {
OverloadDemo obj = new OverloadDemo();
[Link](4, 5); // ❌ Ambiguous now
}
}
Output: Compile time error
[Link]: error: reference to add is ambiguous
[Link](4, 5); // ? Ambiguous now
^
both method add(int,long) in OverloadDemo and method add(long,int) in
OverloadDemo match
1 error
Method Overriding In Java:-

Method overriding allows a subclass to provide a specific implementation of a


method already defined in its parent class. This is an example of runtime
polymorphism, where the method call is resolved at runtime. Overriding is
essential for achieving dynamic behavior and adhering to the principles of
inheritance and abstraction in OOP.

Rules Of Method Overriding In Java


1. The method must have the same name, return type, and parameter list as
the parent class method.
2. The overriding method cannot have a more restrictive access modifier than
the overridden method.
3. Only inherited methods can be overridden. This also means that static, final,
or private methods cannot be overridden.
4. The overriding method can throw the same or narrower checked exceptions.
5. Requires inheritance between parent and child classes.

Example:
class Parent {
void showMessage() {
[Link]("This is the parent class message.");
}
}

class Child extends Parent {


@Override
void showMessage() {
[Link]("This is the child class message.");
}
}

public class Main {


public static void main(String[] args) {

Parent obj1 = new Parent();


Parent obj2 = new Child();

[Link](); // Calls parent class method


[Link](); // Calls child class method
}
}
Output:
This is the parent class message.
This is the child class message.

Dynamic Method Dispatch:


Dynamic method dispatch is a fundamental concept in object-oriented
programming, particularly in Java, where the decision of which method to call is
made at runtime rather than compile time. This mechanism allows Java to execute
the overridden method of a subclass based on the actual object type, enabling
runtime polymorphism.

Upcasting: In this approach, we're creating an object of the Child class but
assigning it to a reference variable obj of the Parent type.
Syntax Of Upcasting For Dynamic Method Dispatch In Java:

SuperclassReference = new Subclass(); // Upcasting

Code Example:
class Vehicle {
void drive() {
[Link]("Driving a vehicle");
}
}
class Car extends Vehicle {
void drive() {
[Link]("Driving a car");
}
}
class Main {
public static void main(String[] args)
{
Vehicle vehicle1 = new Vehicle(); // Creating a Vehicle object
Vehicle vehicle2 = new Car(); // Upcasting: Creating a Car object but referring to it
as a Vehicle

[Link](); // Output: Driving a vehicle


[Link](); // Output: Driving a car//
}
}
Output:
Driving a vehicle
Driving a car
Abstraction in Java

Abstraction is a process of hiding the implementation details and showing only


functionality to the user.

Another way, it shows only essential things to the user and hides the internal
details, for example, sending SMS where we type the text and send the message.
We don't know the internal processing about the message delivery.

Ways to achieve Abstraction


There are two ways to achieve abstraction in java
1. Abstract class (0 to 100%)
2. Interface (100%)

Concrete class:
 A concrete class is one which contains fully defined methods. Defined
methods are also known as implemented or concrete methods. With respect
to concrete class, we can create an object of that class directly.

Abstract class:
 A class that is declared using “abstract” keyword is known as abstract
class. It can have abstract methods (methods without body) as well as
concrete methods (regular methods with body). A normal class(non-abstract
class) cannot have abstract methods.
 An abstract class is one which contains some defined methods and some
undefined methods. Undefined methods are also known as unimplemented
or abstract methods. Abstract method is one which does not contain any
definition. To make the method as abstract we have to use a keyword called
“abstract” before the function declaration.
In java, the following some important observations about abstract classes are as
follows:
 An instance (object) of an abstract class cannot be created.
 Constructors are allowed.
 We can have an abstract class without any abstract method.
 There can be a final method in abstract class but any abstract method in
class(abstract class) cannot be declared as final or in simpler terms final
method cannot be abstract itself as it will yield an error: “Illegal
combination of modifiers: abstract and final”
 We can define static methods in an abstract class
 We can use the abstract keyword for declaring top-level classes
(Outer class) as well as inner classes as abstract
 If a class contains at least one abstract method then compulsory should
declare a class as abstract
 If the Child class is unable to provide implementation to all abstract
methods of the Parent class then we should declare that Child class as
abstract so that the next level Child class should provide implementation
to the remaining abstract method.
Syntax for abstract method:
abstract return_type method_name (parameters list);
Example 1:
abstract class A
{
abstract void callme();
// concrete methods are still allowed in abstract classes
void callmetoo()
{
[Link]("This is a concrete method.");
}
}
class B extends A
Output:
{ B's implementation of callme.
void callme() This is a concrete method.
{
[Link]("B's implementation of callme.");
}
}
class AbstractDemo
{
public static void main(String args[])
{
B b = new B();
[Link]();
[Link]();
}}
Notice that no objects of class A are declared in the program. As mentioned, it is
not possible to instantiate an abstract class.
One other point: class A implements a concrete method called callmetoo()
Example 2:
abstract class Bike
{
static int speed=70;
Bike() //constructor
{
[Link]("Bike is created");
}
abstract void run(); //abstrct method
static void runSpeed() //static method
{
[Link]("Speed:"+speed);
}
final void changGear() //final method
{
[Link]("Gear changed");
}
}
class Honda extends Bike{
void run()
{
[Link]("Running safely");
}
}
abstract class Abstract{ Output:
public static void main(String[] args) { Bike is created
Running safely
Bike b=new Honda(); Speed:70
[Link](); Gear changed

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

Interface
 Multiple inheritance of classes is not permitted in Java.
 To some extent, this restriction can be overcome through interfaces.
 A class may implement more than one interface besides having one super
class.
 An interface can extend one or more interfaces, and a class can also
implement more than one interface.
 An interface is a collection of constants and abstract methods that are
implemented by a class.
 An interface cannot implement itself like a class;
 An interface just contains the method head, and there is no method body. The
class that implements the interface contains the full definition of the method.
Syntax:
interface interfaceName{
}

Interface fields are public, static and final by default, and the methods are public and abstract.
 By default any attribute of interface is public, static and final, so we don’t
need to provide access modifiers to the attributes but if we do, compiler
doesn’t complaint about it either.
Attributes (Variables in Interface)
Any variable declared inside an interface is automatically:
 public (accessible everywhere)
 static (belongs to interface, not to instance)
 final (constant – cannot be changed after initialization)
interface Test {
int VALUE = 100; // same as public static final int VALUE = 100;
}
 By default interface methods are implicitly abstract and public, it makes
total sense because the method don’t have body and so that subclasses can
provide the method implementation.
By default, methods in an interface are:
 public (accessible to implementing classes)
 abstract (no body, must be overridden in implementing class)
interface Shape {
void draw(); // same as public abstract void draw();
}
java 8 and Later (Special Methods in Interfaces):
 default methods → have a body (implementation inside interface).
 static methods → belong to interface, not object.
Implementation of interface:

Multiple Interfaces:
• Multiple interfaces can also be implemented in Java.
• For this, the class implements all the methods declared in all the interfaces.
• When the class is declared, names of all interfaces are listed after the
keyword
implements and separated by comma.
• As for example, if class A implements interfaces C and D, it is defined as

Example:
interface A {
void methodA();
}
interface B {
void methodB();
}
class MyClass implements A, B {
public void methodA() {
[Link]("Method A implemented");
}
public void methodB() {
[Link]("Method B implemented");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
[Link]();
[Link]();
}
}
Another Example:
interface X {
void methodX();
}

interface Y extends X { // interface extending another interface


void methodY();
}

class Demo implements Y {


public void methodX() {
[Link]("Method X implemented");
}
public void methodY() {
[Link]("Method Y implemented");
}
}
// Main class
public class MainClass {
public static void main(String[] args) {
// Using interface reference
Y obj = new Demo();

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

Output:
Method X implemented
Method Y implemented

Key Notes:
 A class implements an interface.
 Must provide implementation for all abstract methods of the interface.
 One class can implement multiple interfaces.
 An interface can extend another interface.
 Objects are created from the implementing class, not the interface.

Nested Interface:
 A nested interface is an interface declared inside another class or
interface.
 It is also called an inner interface.

By default:

 If declared inside an interface, it is public and static.


 If declared inside a class, it can have any access modifier (public, private,
protected, default).
Example:

class Outer {
// nested interface
interface Inner {
void display();
} }
// Implementing nested interface
class Demo implements [Link] {
public void display() {
[Link]("Nested Interface inside Class");
} }
public class Main {
public static void main(String[] args) {
[Link] obj = new Demo(); // using [Link] reference
[Link]();
} }
Output:
Nested Interface inside Class

Another Example:
interface Parent {
void parentMethod();
// nested interface
interface Child {
void childMethod();
}
}
// Implementing Parent interface
class A implements Parent {
public void parentMethod() {
[Link]("Parent Method");
}
}
// Implementing nested Child interface
class B implements [Link] {
public void childMethod() {
[Link]("Child Method");
}
}
public class Main2 {
public static void main(String[] args) {
Parent p = new A();
[Link]();
[Link] c = new B();
[Link]();
}
}
Output:
Parent Method
Child Method

Inheritance of Interfaces:
Interface inheritance occurs when one interface extends one or more existing
interfaces, inheriting their members (method signatures and constants), and a
class can then implement the inherited interface, requiring it to provide
implementations for all methods in the entire inheritance chain. This mechanism
allows for creating more complex, specialized interfaces by combining simpler
ones, supporting multiple inheritance, promoting code reuse, and achieving loose
coupling in object-oriented programming languages like Java

Multiple Inheritance (Interface Extends Multiple Interfaces)


interface A {
void methodA();
}
interface B {
void methodB();
}
interface C extends A, B { // C extends both A and B
void methodC();
}
class Demo implements C {
public void methodA() {
[Link]("Method A");
}
public void methodB() {
[Link]("Method B");
}
public void methodC() {
[Link]("Method C");
}
}
public class MainClass {
public static void main(String[] args) {
C obj = new Demo();
[Link]();
[Link]();
[Link]();
}
}
Output:
Method A
Method B
Method C

Key Note:
 class extends class → single inheritance.
 interface extends interfaces → multiple inheritance possible.

 class implements interface → must provide method definitions.

Default Methods in Interface:


Default methods in interfaces, introduced in Java 8, provide a way to add new
methods to an interface without breaking existing classes that implement that
interface. Before Java 8, adding a new method to an interface required all
implementing classes to provide an implementation for that new method, which
could lead to significant code changes in large projects.
Syntax:

Example:
interface Vehicle {
void start(); // abstract method
default void fuel() { // default method
[Link]("Filling fuel...");
}
}
class Car implements Vehicle {
public void start() {
[Link]("Car starting...");
}
}
public class Main {
public static void main(String[] args) {
Vehicle v = new Car();
[Link]();
[Link](); // calls default method
}
}
Output:
Car starting...
Filling fuel…

Static Methods in Interface:


 Introduced in Java 8 along with default methods.
 Declared using the keyword static inside an interface.
 Unlike default methods, static methods cannot be inherited by implementing
classes.
 They are accessed using the interface name, not through an object.
Syntax:

Example:
interface MathUtils {
static int add(int a, int b) {
return a + b;
}
static int multiply(int a, int b) {
return a * b;
}
}
public class Main {
public static void main(String[] args) {
// calling static methods using interface name
[Link]("Addition: " + [Link](5, 3));
[Link]("Multiplication: " + [Link](4, 2));
}
}
Output:
Addition: 8
Multiplication: 8

Functional Interfaces:
A functional interface in Java is an interface that contains only one abstract
method. These are also known as Single Abstract Method (SAM)
interfaces. Introduced in Java 8, functional interfaces play a crucial role in enabling
functional programming concepts like lambda expressions and method
references.
Example: By using Anonymous class
@FunctionalInterface
interface A {
void show();
}

class FuncInterface {
public static void main(String[] a) {
A obj = new A() {
public void show() {
[Link]("In show");
}
};
[Link]();
}}

Output:
In show

Lambda Expressions:

Lambda expressions are one of the most significant additions to the Java
programming language in recent years. They were introduced in Java 8 and are a
way to write more concise and expressive code. Lambda expressions allow us to
define and pass around blocks of code, known as functional interfaces, making it
easier to write code that is both more readable and maintainable.

syntax:
(argument list) -> { body of the expression }

Components:
 Argument List: Parameters for the lambda expression
 Arrow Token (->): Separates the parameter list and the body
 Body: Logic to be executed

Example: by using Lambda expressions


@FunctionalInterface
interface A {
void show(int i);
}

class FuncInterface {
public static void main(String[] a) {
A obj = ( i) -> [Link]("In show ");
[Link](10);
}
}
Output:
In Show
Example : With parameters

Lambda Usage:
Output:
Sum = 15
Example : With return value

Rules for Functional Interface:


 Must have exactly one abstract method.
 Can have any number of default or static methods.
 Can use @FunctionalInterface annotation (optional but recommended).
 Can be implemented using anonymous classes or lambda expressions.

Annotations in Java
Annotations in Java are a form of metadata that provide additional information
about the program. They do not change the action of a compiled program but
can be used by the compiler or runtime for processing.
Key Points:
 Annotations start with ‘@’.
 Annotations do not change the action of a compiled program.
 Annotations help to associate metadata (information) to the program elements
i.e. instance variables, constructors, methods, classes, etc.
 Annotations are not pure comments as they can change the way a program is
treated by the compiler.
Categories of Annotations
There are broadly 5 categories of annotations as listed:
 Marker Annotations
 Single value Annotations
 Full Annotations
 Type Annotations
 Repeating Annotations

Category Example Key Point


Marker @Override No elements
Single- @SuppressWarnings("unchec
One element (value)
value ked")
Full @Info(author="A", date="D") Multiple elements
Type @NonNull String name Applied to types
Multiple same
Repeating @Schedule(...) multiple
annotations

Example:
class MarkerExample {
@Override
public String toString() {
return "MarkerExample class";
}

@Deprecated
void oldMethod() {
[Link]("This method is deprecated");
}
public static void main(String[] args) {
MarkerExample obj = new MarkerExample();
[Link](obj);
[Link](); // Warning: deprecated
}
}
Output:
MarkerExample class
This method is deprecated

You might also like