[Go to site: main page, start]

0% found this document useful (0 votes)
6 views68 pages

Java Module3

The document discusses the concept of polymorphism in Java, highlighting its ability to allow one interface for multiple data types and methods. It explains method overloading as a form of compile-time polymorphism, detailing rules, advantages, and guidelines for effective usage. Additionally, it covers argument passing, recursion, and the QuickSort algorithm, emphasizing the benefits and drawbacks of recursive methods.

Uploaded by

nithishkumarm106
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)
6 views68 pages

Java Module3

The document discusses the concept of polymorphism in Java, highlighting its ability to allow one interface for multiple data types and methods. It explains method overloading as a form of compile-time polymorphism, detailing rules, advantages, and guidelines for effective usage. Additionally, it covers argument passing, recursion, and the QuickSort algorithm, emphasizing the benefits and drawbacks of recursive methods.

Uploaded by

nithishkumarm106
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

OOPs with JAVA(M23BCS306B)

Module – 3

Polymorphism
 The term polymorphism comes from Greek, meaning “many forms.”
 It allows one interface to be used for a general class of actions.
 The specific action executed depends on the situation or the type of data.
Example (Stack)

 Suppose a program needs three stacks:


o One for integers
o One for floats
o One for characters
The algorithm for all stacks is the same, only the data type differs.

 In non-OOP languages, you must write three different sets of functions with different
names. In Java (OOP), polymorphism allows one common set of method names, reused
with different data types.
 Polymorphism is often described as “one interface, multiple methods.”
 You can design a generic interface for related operations. This reduces complexity because:
You use the same method name. The compiler decides which version of the method to call.
Eg: Dog Analogy
A dog’s sense of smell behaves polymorphically. If it smells a cat, it barks and chases. If it
smells food, it salivates and runs to the bowl. Same “interface” (smell), different actions
depending on the “data” (what it smells).

Method Overloading
 When a class has multiple methods with the same name but different parameter lists, the
methods are overloaded.
 Method overloading is one way Java implements compile-time polymorphism.
How It Works
When an overloaded method is called, Java decides which method to invoke based on:
o Number of parameters
o Type of parameters.
Rules for Overloading
o Methods must differ in type and/or number of parameters.
o Methods may have different return types.
o But return type alone cannot differentiate overloaded methods.
Why It Is Useful
o Makes code more readable and user-friendly.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 1


OOPs with JAVA(M23BCS306B)
Module – 3

o Allows methods that perform similar tasks to reuse the same name.
Eg: A method sum() can be overloaded as:
 sum(int a, int b)
 sum(double a, double b)
 sum(int a, int b, int c)

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 2


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, test() is overloaded four times.


 The first version takes no parameters.
 The second takes one integer parameter.
 The third takes two integer parameters.
 The fourth takes one double parameter. The fact that the fourth version of test() also returns
a value is of no consequence relative to overloading, since return types do not play a role
in overload resolution.
When an overloaded method is called, Java looks for a match between the arguments
used to call the method and the method’s parameters. However, this match need not always
be exact. In some cases, Java’s automatic type conversions can play a role in overload
resolution. For example, consider the following program:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 3


OOPs with JAVA(M23BCS306B)
Module – 3

This program generates the following output:

How Java Resolves Overloaded Methods


 Java first looks for an exact match of the method signature.
Example: If test(int) exists, Java will call it.
 If no exact match is found, Java tries automatic type conversion (e.g., int → double) to
find a suitable method.
 In the example, since test(int) is not defined, Java converts the integer argument to double
and calls test(double).
 Automatic conversions are used only when an exact match is not available.
Overloading as a Form of Polymorphism
 Method overloading supports the concept of “one interface, multiple methods.”

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 4


OOPs with JAVA(M23BCS306B)
Module – 3

 You use one method name to perform similar operations on different data types.
 Java avoids this complexity by allowing all versions to share the same name (e.g.,
[Link]() works for int, long, float, double).
 The compiler automatically selects the correct version based on the argument’s data
type.
Advantages of Method Overloading
 Allows related methods to be accessed using one common name.
 Reduces the number of different function names a programmer must remember.
 Improves readability, maintainability, and conceptual clarity.
 Helps manage complexity in large programs by grouping similar operations.
4. Design Guidelines for Overloading
 All overloaded versions can perform any activity, but:
o They should be conceptually related.
 Overloading unrelated methods using the same name is not recommended.
o Example of poor use: Using the name sqr for:
 square of an integer, and
 square root of a float
(These operations are different and should not share a name.)
 Overloading should be used only when methods perform similar or related tasks.
Overloading Constructors
In addition to overloading normal methods, you can also overload constructor
methods. In fact, for most real-world classes that you create, overloaded constructors will be
the norm, not the exception. Following is the latest version of Box

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 5


OOPs with JAVA(M23BCS306B)
Module – 3

Box() constructor requires three parameters. This means that all declarations of Box objects
must pass three arguments to the Box() constructor. For example, the following statement is
currently invalid:
Box ob = new Box();
Since Box() requires three arguments, it’s an error to call it without them.
Overload the Box constructor so that it handles 3 arguments. Here is a program that contains
an improved version of Box

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 6


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, the proper overloaded constructor is called based upon the arguments
specified when new is executed.
Using Objects as Parameters
So far, we have only been using simple types as parameters to methods. However, it is both
correct and common to pass objects to methods. For example, consider the following short
program

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 7


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, the equalTo( ) method inside Test compares two objects for equality and
returns the result. That is, it compares the invoking object with the one that it is passed. If they
contain the same values, then the method returns true. Otherwise, it returns false. Notice that
the parameter o in equalTo( ) specifies Test as its type. Although Test is a class type created
by the program, it is used in just the same way as Java’s built-in types.
One of the most common uses of object parameters involves constructors.
Frequently, you will want to construct a new object so that it is initially the same as some
existing object. To do this, you must define a constructor that takes an object of its class as a
parameter. For example, the following version of Box allows one object to initialize another:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 8


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 9


OOPs with JAVA(M23BCS306B)
Module – 3

As you will see when you begin to create your own classes, providing many forms of
constructors is usually required to allow objects to be constructed in a convenient and efficient
manner.
Argument Passing
Two General Ways to Pass Arguments to a method
1. Call-by-Value
 The value of the argument is copied into the method’s parameter.
 The method works on the copy, not the original value.
 Changes inside the method do NOT affect the original argument.
2. Call-by-Reference
 Instead of copying the value, a reference (address) to the original argument is passed.
 The method can directly access and modify the actual argument.
 Changes inside the method DO affect the original variable.
How Java Passes Arguments
 Java always uses call-by-value.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 10


OOPs with JAVA(M23BCS306B)
Module – 3

o The behavior depends on whether you pass a primitive type or a reference type.
Passing Primitive Types in Java
 When a primitive (int, float, double, etc.) is passed:
o A copy of its value is passed to the method.
o The method works only on this local copy.
o The original value remains unchanged.
How Java Passes Reference Types (Objects & Arrays)
 When an object or array is passed, Java passes the value of the reference.
 This means the method receives a copy of the reference, but it still points to the same
object.
 So: Changing the object’s data → affects the original [Link] the reference
inside the method → does NOT affect the original reference.
Note:
 Object contents can be changed.
 Reference itself cannot be changed from the caller’s side.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 11


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, the operations that occur inside meth( ) have no effect on the values of a and
b used in the call; their values here did not change to 30 and 10.
Note: Primitive types → copy of value
Objects → copy of reference (so object contents can change)

This program generates the following output:

As you can see, in this case, the actions inside meth( ) have affected the object used as an
argument.
REMEMBER When an object reference is passed to a method, the reference itself is passed
by use of ca l-by value. However, since the value being passed refers to an object, the copy of
that value will still refer to the same object that its corresponding argument does.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 12


OOPs with JAVA(M23BCS306B)
Module – 3

Returning Objects
A method can return any type of data, including class types that you create. For example, in the
following program, the incrByTen( ) method returns an object in which the value of a is ten
greater than it is in the invoking object:

The output generated by this program is shown here:

As you can see, each time incrByTen( ) is invoked, a new object is created, and a reference to
it is returned to the calling routine.
The preceding program makes another important point: Since all objects are
dynamically allocated using new, you don’t need to worry about an object going out of scope
because the method in which it was created terminates. The object will continue to exist as long
as there is a reference to it somewhere in your program. When there are no references to it, the
object will be reclaimed the next time garbage collection takes place.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 13


OOPs with JAVA(M23BCS306B)
Module – 3

Recursion
Java supports recursion. Recursion is the process of defining something in terms of itself. As
it relates to Java programming, recursion is the attribute that allows a method to call itself. A
method that calls itself is said to be recursive.
The classic example of recursion is the computation of the factorial of a number. The
factorial of a number N is the product of all the whole numbers between 1 and N. For example,
3 factorial is 1 × 2 × 3, or 6. Here is how a factorial can be computed by use of a recursive
method:

How the recursive fact() method works


 A recursive method is a method that calls itself.
 In the factorial method:
o If n == 1, the method returns 1.
o Otherwise, it returns n * fact(n − 1).
 This process continues until the base case (n == 1) is reached.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 14


OOPs with JAVA(M23BCS306B)
Module – 3

Example: Calculating factorial of 3


 First call: fact(3)
→ calls fact(2)
 Second call: fact(2)
→ calls fact(1)
 Third call: fact(1)
→ returns 1 (base case)
 Return sequence:
o fact(2) = 2 × 1 = 2
o fact(3) = 3 × 2 = 6
 Final result: 6
How recursion works internally (stack behavior)
 Each time a method calls itself:
o A new copy of local variables and parameters is created.
o This new set is stored on the stack.
 When a call finishes:
o Its variables are removed from the stack.
o Control returns to the previous call.
 This creates a “telescope effect”:
o Calls expand outward (going deeper)
o Then collapse inward (returning results)
Disadvantages of recursion
 Recursive methods are sometimes slower than iterative methods:
o Because each recursive call requires pushing a new frame on the stack.
 Too many recursive calls may cause a stack overflow error:
o Each new call uses stack space.
o If recursion is very deep or infinite, the stack may be exhausted.
Advantages of recursion
 Recursive solutions can be simpler, cleaner, and closer to the mathematical definition.
 Many algorithms are easier to express recursively:
o Example: QuickSort
o Many Artificial Intelligence search algorithms

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 15


OOPs with JAVA(M23BCS306B)
Module – 3

 Recursive code is often more elegant and easier to understand compared to complicated
loops.
How QuickSort Works
1. Choose a pivot element.
(In this program, the last element is chosen as pivot.)
2. Rearrange (partition) the array so that:
o Elements smaller than pivot → left side
o Elements greater than pivot → right side
3. Return the position of the pivot after partitioning.
4. Recursively apply QuickSort on:
o Left sub-array (before pivot)
o Right sub-array (after pivot)
5. Recursion continues until the entire array is sorted.

// Java program for implementation of QuickSort


class QuickSort
{
int partition(int a[], int low, int high)
{
int pivot = a[high];
int i = (low-1);
for (int j=low; j<high; j++)
{
// If current element is smaller than or equal to pivot
if (a[j] <= pivot)
{
i++;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 16


OOPs with JAVA(M23BCS306B)
Module – 3

}
int temp = a[i+1];
a[i+1] = a[high];
a[high] = temp;

return i+1;
}
/* The main function that implements QuickSort()
a[] --> Array to be sorted,
l --> Starting index,
h --> Ending index */
void sort(int a[], int l, int h)
{
if (l < h)
{
int pi = partition(a, l, h);
// Recursively sort elements before partition and after partition
sort(a, l, pi-1);
sort(a, pi+1, h);
}
}
// Driver program
public static void main(String args[])
{
int a[] = {10, 7, 8, 9, 1, 5};
int n = [Link];
QuickSort ob = new QuickSort();
[Link](a, 0, n-1);
for (int i=0; i<n; ++i)
[Link](a[i]+" ");
}

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 17


OOPs with JAVA(M23BCS306B)
Module – 3

This program generates the following output:

Introducing Access Control


Encapsulation
 Encapsulation links data with the code (methods) that manipulates it.
 Provides access control over class members.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 18


OOPs with JAVA(M23BCS306B)
Module – 3

 Allows creating a “black box”:


o Users can use the class.
o But the internal implementation is hidden and protected from tampering.
Access Control importance
 Prevents misuse of data.
 Ensures that data can be accessed only through well-defined methods.
 Example:
o Stack class has push() and pop() methods for controlled access.
o Without proper access control, other parts of the program could bypass these
methods and access the stack directly → unsafe.
How Access Control Works in Java
 Access to a member is determined by the access modifier attached to its declaration.
 Java provides a rich set of access modifiers:
1. public
 Member can be accessed from anywhere, inside or outside the package.
2. private
 Member can be accessed only within its own class.
 Typical use: data members of a class.
3. protected
 Member can be accessed in subclasses and within the same package.
 Relevant mainly for inheritance.
4. default (no modifier)
 Member is accessible only within the same package.
 Not accessible outside the package.
Examples of Access Control
 public is why main() works:
o Called by Java run-time system outside the class.
 private ensures that:
o Data members are hidden.
o Methods can also be made private if they are meant for internal use only.
 default access is package-private:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 19


OOPs with JAVA(M23BCS306B)
Module – 3

o Works within a package but not outside it.


Best Practices
 Restrict data members to private.
 Provide public methods (getters/setters) for controlled access.
 Make helper methods private if they are internal to the class logic.
 Avoid exposing internal implementation; use encapsulation to maintain safety and
modularity.

public int i;
private double j;
private int myMethod(int a, char b) { //……}
To understand the effects of public and private access, consider the following program:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 20


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, inside the Test class, a uses default access, which for this example is the same
as specifying public. b is explicitly specified as public. Member c is given private access. This
means that it cannot be accessed by code outside of its class. So, inside the AccessTest class, c
cannot be used directly. It must be accessed through its public methods: setc( ) and getc( ). If
you were to remove the comment symbol from the beginning of the following line,
ob.c = 100; // Error!
then you would not be able to compile this program because of the access violation.
To see how access control can be applied to a more practical example, consider the
following improved version of the Stack class.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 21


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, now both stck, which holds the stack, and tos, which is the index of
the top of the stack, are specified as private. This means that they cannot be accessed or altered
except through push( ) and pop( ). Making tos private, for example, prevents other parts of
your program from inadvertently setting it to a value that is beyond the end of the stck array.
The following program demonstrates the improved Stack class. Try removing the
commented-out lines to prove to yourself that the stck and tos members are, indeed,
inaccessible.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 22


OOPs with JAVA(M23BCS306B)
Module – 3

Understanding static
Purpose of static members
 Sometimes you need a class member that works independently of any object.
 Normally, class members are accessed through objects, but static members are
accessible without creating an object.
Declaring static members
 Use the keyword static before a variable or method.
 Static members can be accessed:
o Before any object is created
o Without using an object reference
 The most common static method is main().
 main() must be static because Java calls it before objects are created.

Static variables (class variables)

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 23


OOPs with JAVA(M23BCS306B)
Module – 3

 Static variable can also be called as shared variable.


 Only one copy exists for the entire class.
 All objects of the class share the same static variable.
 They behave like global variables, but restricted within the class.

Methods declared as static have several restrictions:


 They can only directly call other static methods of their class.
 They can only directly access static variables of their class.
 They cannot refer to this or super in any way.
If you need to do computation in order to initialize your static variables, you can declare
a static block that gets executed exactly once, when the class is first loaded. The following
example shows a class that has a static method, some static variables, and a static initialization
block:

As soon as the UseStatic class is loaded, all of the static statements are run. First, a is set to 3,
then the static block executes, which prints a message and then initializes b to a*4 or 12. Then
main( ) is called, which calls meth( ), passing 42 to x. The three println( ) statements refer to
the two static variables a and b, as well as to the parameter x.
Here is the output of the program:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 24


OOPs with JAVA(M23BCS306B)
Module – 3

Outside of the class in which they are defined, static methods and variables can be used
independently of any object. To do so, you need only specify the name of their class followed
by the dot operator.
For example, if you wish to call a static method from outside its class, you can do so
using the following general form:
[Link]( )
Here, classname is the name of the class in which the static method is declared. As you
can see, this format is similar to that used to call non-static methods through object-reference
variables. A static variable can be accessed in the same way—by use of the dot operator on the
name of the class. This is how Java implements a controlled version of global methods and
global variables.
Here is an example. Inside main( ), the static method callme( ) and the static variable
b are accessed through their class name StaticDemo.

Here is the output of this program

Introducing final
 A final field cannot be modified after it is assigned.
 It behaves like a constant in Java.
Ways to initialize a final field
There are two valid methods:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 25


OOPs with JAVA(M23BCS306B)
Module – 3

1. Assign a value at the time of declaration


final int FILE_OPEN = 1;
2. Assign a value in the constructor
Useful when each object needs its own constant-like value.
Usage
 Once initialized, a final field’s value cannot be changed anywhere in the program.
 Constants are often written in UPPERCASE by convention.
final with other elements
a. final parameters
 A final method parameter cannot be modified inside the method body.
b. final local variables
 A final local variable can be assigned only once.
c. final methods
 A final method cannot be overridden in a subclass.
Arrays Revisited
There is a special array attribute that you will want to take advantage of. Specifically, the size
of an array—that is, the number of elements that an array can hold—is found in its length
instance variable. All arrays have this variable, and it will always hold the size of the array.
Here is a program that demonstrates this property:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 26


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, the size of each array is displayed. Keep in mind that the value of length
has nothing to do with the number of elements that are actually in use. It only reflects the
number of elements that the array is designed to hold.
You can put the length member to good use in many situations. For example, here is
an improved version of the Stack class. As you might recall, the earlier versions of this class
always created a ten-element stack. The following version lets you create stacks of any size.
The value of [Link] is used to prevent the stack from overflowing.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 27


OOPs with JAVA(M23BCS306B)
Module – 3

Notice that the program creates two stacks:


 one five elements deep
 other eight elements deep.
As you can see, the fact that arrays maintain their own length information makes it easy to
create stacks of any size.
Introducing Nested and Inner Classes
 A class defined inside another class is called a nested class.
 The scope of a nested class is limited to its enclosing (outer) class.
 If class B is defined inside class A, then:
o B does not exist independently of A.
Access Rules
a. Nested class access
 A nested class can access all members (including private) of its outer class.
b. Enclosing class access
 The outer (enclosing) class cannot directly access the members of the nested class.
Types of Nested Classes
There are two types:
1. Static Nested Class

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 28


OOPs with JAVA(M23BCS306B)
Module – 3

 Declared using the static keyword.


 Behaves like a static member of the outer class.
 Cannot directly access non-static members of the outer class.
 Must access outer class non-static members using an object.
2. Inner Class (Non-static Nested Class)
 A non-static nested class.
 Can directly access all variables and methods of the outer class.
 Behaves like any other instance member of the outer class.
The following program illustrates how to define and use an inner class. The class named Outer
has one instance variable named outer_x, one instance method named test( ), and defines one
inner class called Inner.

In the program, an inner class named Inner is defined within the scope of class Outer.
Therefore, any code in class Inner can directly access the variable outer_x. An instance
method named display( ) is defined inside Inner. This method displays outer_x on the
standard output stream. The main( ) method of InnerClassDemo creates an instance of class
Outer and invokes its test( ) method. That method creates an instance of class Inner, and the
display( ) method is called.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 29


OOPs with JAVA(M23BCS306B)
Module – 3

It is important to realize that an instance of Inner can be created only in the context of
class Outer. The Java compiler generates an error message otherwise. In general, an inner
class instance is often created by code within its enclosing scope, as the example does.
As explained, an inner class has access to all of the members of its enclosing class, but
the reverse is not true. Members of the inner class are known only within the scope of the inner
class and may not be used by the outer class. For example:

Here, y is declared as an instance variable of Inner. Thus, it is not known outside of


that class and it cannot be used by showy( ).
Although we have been focusing on inner classes declared as members within an outer
class scope, it is possible to define inner classes within any block scope. For example, you can
define a nested class within the block defined by a method or even within the body of a for
loop, as this next program shows:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 30


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 31


OOPs with JAVA(M23BCS306B)
Module – 3

Inheritance
 Inheritance is a cornerstone of object-oriented programming (OOP).
 Inheritance is an object-oriented programming feature that allows a class (subclass) to
acquire the properties and behaviours (fields and methods) of another class (superclass),
enabling code reuse, hierarchical classification, and creation of specialized versions of
general classes
 It allows creating hierarchical relationships between classes.
 Promotes code reuse and logical classification.
How Inheritance Works
 You can define a general class (superclass/base/parent) that contains traits common to
a group of related items.
 Specific classes (subclasses/derived/child) can inherit from the general class and add
their unique features.
4. Features of Subclasses
 A subclass inherits all members (fields and methods) of its superclass.
 Can add new members unique to itself.
 Represents a specialized version of the superclass.
Inheritance Basics
In order to have your class inherit from a superclass, you simply incorporate the definition of
the superclass into your class using the extends keyword. To see how, let’s begin with a short
example. The following program creates a superclass called A and a subclass called B. Notice
how the keyword extends is used to create a subclass of A.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 32


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 33


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 34


OOPs with JAVA(M23BCS306B)
Module – 3

As you can see, the subclass B includes all of the members of its superclass, A. This is why
subOb can access i and j and call showij( ). Also, inside sum( ), i and j can be referred to
directly, as if they were part of B.
Even though A is a superclass for B, it is also a completely independent, stand-alone
class. Being a superclass for a subclass does not mean that the superclass cannot be used by
itself. Further, a subclass can be a superclass for another subclass.
The general form/syntax of a class declaration that inherits a superclass is shown here:
class subclass-name extends superclass-name{
//body of class
}
You can only specify one superclass for any subclass that you create. Java does not support the
inheritance of multiple superclasses into a single subclass. You can, as stated, create a
hierarchy of inheritance in which a subclass becomes a superclass of another subclass.
However, no class can be a superclass of itself.
Member Access and Inheritance
Inheritance and Member Access
 A subclass inherits all members (fields and methods) of its superclass.
 However, private members of the superclass are not accessible directly in the
subclass.
Why Private Members Are Not Accessible
 Private members are hidden from other classes, including subclasses.
 This preserves encapsulation, preventing subclasses from modifying internal details of
the superclass directly.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 35


OOPs with JAVA(M23BCS306B)
Module – 3

This program will not compile because the use of j inside the sum( ) method of B causes an
access violation. Since j is declared as private, it is only accessible by other members of its
own class. Subclasses have no access to it.
A class member that has been declared as private will remain private to its class. It is not
accessible by any code outside its class, including subclasses.
A More Practical Example
The new class will contain a box’s width, height, depth, and weight.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 36


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 37


OOPs with JAVA(M23BCS306B)
Module – 3

BoxWeight inherits all of the characteristics of Box and adds to them the weight component.
It is not necessary for BoxWeight to re-create all of the features found in Box. It can simply
extend Box to meet its own purposes.
A major advantage of inheritance is that once you have created a superclass that defines
the attributes common to a set of objects, it can be used to create any number of more specific
subclasses. Each subclass can precisely tailor its own classification. For example, the
following class inherits Box and adds a color attribute:
Remember, once you have created a superclass that defines the general aspects of an object,
that superclass can be inherited to form specialized classes. Each subclass simply adds its own
unique attributes. This is the essence of inheritance

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 38


OOPs with JAVA(M23BCS306B)
Module – 3

A Superclass Variable Can Reference a Subclass Object


A reference variable of a superclass can be assigned a reference to any subclass derived from
that superclass. For example, consider the following:

Here, weightbox is a reference to BoxWeight objects, and plainbox is a reference to Box


objects. Since BoxWeight is a subclass of Box, it is permissible to assign plainbox a reference
to the weightbox object.
 Superclass: Box
o Fields: width, height, depth
 Subclass: BoxWeight
o Fields: weight (added in subclass)
 Box plainBox = new BoxWeight();
o plainBox can access: width, height, depth (from Box)
o plainBox cannot access: weight (added in BoxWeight)

Reference Type Determines Access


 In Java, it is the type of the reference variable, not the type of the actual object, that
determines which members can be accessed.
 Even if a reference points to a subclass object, you can only access members defined
in the reference type (class).

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 39


OOPs with JAVA(M23BCS306B)
Module – 3

Using super
Problem with Direct Access in Subclasses
 In previous examples, subclasses like BoxWeight directly initialized fields (width,
height, depth) from the superclass Box.
 Issues with this approach:
1. Code duplication – same initialization code exists in both superclass and
subclass.
2. Access violation – requires the superclass fields to be non-private, which
breaks encapsulation.
 If the superclass keeps its members private, the subclass cannot access them directly.
Solution: The super Keyword
 Java provides super to allow a subclass to refer to its immediate superclass safely.
 super has two main uses:
a) Calling the superclass constructor
b) Accessing a hidden member of the superclass
Key Points
 super() must be the first statement in a subclass constructor if used.
 super helps maintain encapsulation while allowing proper initialization and member
access.
 Avoids code duplication and direct field access, making inheritance more robust.
Using super to Call Superclass Constructors
A subclass can call a constructor defined by its superclass by use of the following form of
super:
super(arg-list);
Here, arg-list specifies any arguments needed by the constructor in the superclass. super( )
must always be the first statement executed inside a subclass’s constructor.
To see how super( ) is used, consider this improved version of the BoxWeight class:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 40


OOPs with JAVA(M23BCS306B)
Module – 3

Here, BoxWeight( ) calls super( ) with the arguments w, h, and d. This causes the Box
constructor to be called, which initializes width, height, and depth using these values.
BoxWeight no longer initializes these values itself. It only needs to initialize the value unique
to it: weight. This leaves Box free to make these values private if desired.
In the preceding example, super( ) was called with three arguments. Since constructors
can be overloaded, super( ) can be called using any form defined by the superclass. The
constructor executed will be the one that matches the arguments. For example, here is a
complete implementation of BoxWeight that provides constructors for the various ways that a
box can be constructed. In each case, super( ) is called using the appropriate arguments. Notice
that width, height, and depth have been made private within Box.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 41


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 42


OOPs with JAVA(M23BCS306B)
Module – 3

Passing Subclass Objects to Superclass Constructor


 super() can be used to call a superclass constructor from a subclass.
 Even if super() is passed an object of the subclass type (e.g., BoxWeight), it can still
invoke a superclass constructor (e.g., Box(Box ob)).
 Reason: A superclass variable can reference any object derived from that class.
 Note: The superclass only knows about its own members, not the added members of
the subclass.
Immediate Superclass
 super() always refers to the immediate superclass of the calling class.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 43


OOPs with JAVA(M23BCS306B)
Module – 3

 This is true even in a multilevel inheritance hierarchy:


o Subclass → Intermediate class → Superclass
o super() in Subclass calls Intermediate class constructor, not the topmost
superclass.
Position of super()
 super() must be the first statement in a subclass constructor.
 This ensures that the superclass is properly initialized before the subclass adds its
own initializations.
A Second Use for super
[Link]
Here, member can be either a method or an instance variable. This second form of super is
most applicable to situations in which member names of a subclass hide members by the same
name in the superclass. Consider this simple class hierarchy

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 44


OOPs with JAVA(M23BCS306B)
Module – 3

Creating a Multilevel Hierarchy


Multilevel Inheritance
 Multilevel inheritance occurs when a subclass acts as a superclass for another class.
 You can create any number of inheritance layers.
 Example hierarchy:
 A→B→C
o B inherits from A
o C inherits from B
o C therefore inherits from both B and A.
How Members Are Inherited
 Each subclass inherits all members of its immediate superclass.
 Consequently, the lowest subclass in the hierarchy inherits members from all
superclasses above it.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 45


OOPs with JAVA(M23BCS306B)
Module – 3

 Example:
o C inherits all traits of B and A.
Practical Example
 Superclass: Box → defines dimensions (width, height, depth)
 Subclass: BoxWeight → inherits from Box and adds weight
 Subclass of BoxWeight: Shipment → inherits from BoxWeight and Box
o Adds a new field: cost (shipping cost)
 Result:
o Shipment objects have all members of Box and BoxWeight, plus its own cost.
Benefits of Multilevel Inheritance
 Code reuse: Reuse fields and methods across multiple layers.
 Logical classification: Build hierarchies that reflect real-world relationships.
 Extensibility: Subclasses can extend functionality without modifying existing classes.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 46


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 47


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 48


OOPs with JAVA(M23BCS306B)
Module – 3

Inheritance Enables Code Reuse


 The class Shipment inherits all fields and methods from Box and BoxWeight.
 This allows Shipment to reuse existing code instead of rewriting dimension or weight
logic.
 Subclass adds only what is new, such as cost.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 49


OOPs with JAVA(M23BCS306B)
Module – 3

super() Always Refers to the Immediate Superclass


 In a multilevel hierarchy:
o Shipment → immediate superclass = BoxWeight
o BoxWeight → immediate superclass = Box
 Therefore:
o super() in Shipment calls BoxWeight constructor.
o super() in BoxWeight calls Box constructor.
It never skips levels.
Order of Constructor Calling
 Constructors execute top-down, from superclass to subclass.
 Example order:
o Box constructor
o BoxWeight constructor
o Shipment constructor
Passing Arguments “Up the Line”
 If a superclass constructor requires parameters, then:
 Every subclass must pass the required values using super().
 This is mandatory even if:
The subclass does not need those arguments for its own fields.
Example:
Shipment(double w, double h, double d, double m, double c)
{
super(w, h, d, m); // must pass to BoxWeight
cost = c;
}
Why This is Important
 Ensures that each level of the hierarchy initializes its own fields [Link]
encapsulation since subclasses do not directly access superclass private fields.
 Maintains clean, modular, and reusable code.
NOTE: In the preceding program, the entire class hierarchy, including Box, BoxWeight, and
Shipment, is shown a l in one file. This is for your convenience only. In Java, all three classes
could have been placed into their own files and compiled separately. In fact, using separate
files is the norm, not the exception, in creating class hierarchies.
When Constructors Are Executed
 In a class hierarchy, which constructor executes first?
o Example: Subclass B and superclass A

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 50


OOPs with JAVA(M23BCS306B)
Module – 3

o Does A’s constructor execute before B’s, or vice versa?


Rule
 Constructors execute from superclass to subclass.
o First, the constructor of the topmost superclass is executed.
o Then constructors of each subclass in order down the hierarchy.
Role of super()
 super() calls the constructor of the immediate superclass.
 It must be the first statement in a subclass constructor.
 Even if super() is not explicitly used, Java automatically calls the default
(parameterless) constructor of the superclass.
 Constructor execution always follows “top-down” order in the hierarchy:
1. Superclass constructor(s)
2. Subclass constructor(s)
 This ensures all inherited members are initialized before subclass-specific
members.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 51


OOPs with JAVA(M23BCS306B)
Module – 3

Method Overriding
Method Overriding in Java — Explanation
In a class hierarchy, if a subclass defines a method with the same name, return type, and
parameters as a method in its superclass, the subclass overrides the superclass method.
 When you call the method using an object of the subclass, Java executes the subclass
version of the method.
 The superclass method is hidden (but can still be accessed using [Link]()
inside the subclass).
This is runtime polymorphism.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 52


OOPs with JAVA(M23BCS306B)
Module – 3

When show( ) is invoked on an object of type B, the version of show( ) defined within B is
used. That is, the version of show( ) inside B overrides the version declared in A. If you wish
to access the superclass version of an overridden method, you can do so by using super. For
example, in this version of B, the superclass version of show( ) is invoked within the subclass’s
version. This allows all instance variables to be displayed

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 53


OOPs with JAVA(M23BCS306B)
Module – 3

Here, [Link]( ) calls the superclass version of show( ).


Method overriding occurs only when the names and the type signatures of the two
methods are identical. If they are not, then the two methods are simply overloaded. For
example, consider this modified version of the preceding example:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 54


OOPs with JAVA(M23BCS306B)
Module – 3

The version of show( ) in B takes a string parameter. This makes its type signature different
from the one in A, which takes no parameters. Therefore, no overriding (or name hiding) takes
place. Instead, the version of show( ) in B simply overloads the version of show( ) in A.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 55


OOPs with JAVA(M23BCS306B)
Module – 3

Dynamic Method Dispatch


Method overriding is powerful not just because a subclass replaces a method from a superclass,
but because Java chooses the correct method to run at runtime. This is called dynamic
method dispatch.
A superclass reference variable can point to a subclass object:
A ref;
ref = new B(); // superclass ref → subclass object
When you call an overridden method using this reference, Java looks at the actual object, not
the reference type.
 If the object is B, Java runs B’s version.
 If it later refers to C, Java runs C’s version
This selection happens at runtime, enabling runtime polymorphism.
Dynamic dispatch allows Java to:
 support runtime polymorphism
 write generic code that works on objects of different subclasses
 choose behavior at runtime, not compile time
This is what makes Java’s OOP model flexible and extensible.
Here is an example that illustrates dynamic method dispatch:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 56


OOPs with JAVA(M23BCS306B)
Module – 3

This program creates one superclass called A and two subclasses of it, called B and C.
Subclasses B and C override callme( ) declared in A. Inside the main( ) method, objects of type
A, B, and C are declared. Also, a reference of type A, called r, is declared. The program then
in turn assigns a reference to each type of object to r and uses that reference to invoke callme(
). As the output shows, the version of callme( ) executed is determined by the type of object

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 57


OOPs with JAVA(M23BCS306B)
Module – 3

being referred to at the time of the call. Had it been determined by the type of the reference
variable, r, you would see three calls to A’s callme( ) method.
NOTE Readers familiar with C++ or C# wil recognize that overridden methods in Java are
similar to virtual functions in those languages.
Why Overridden Methods?
Polymorphism through Overridden Methods
Overridden methods allow Java to achieve run-time polymorphism. This means the
same method name can behave differently depending on the object that calls it. The superclass
defines the general method, and each subclass provides its own implementation. This is why
polymorphism is often described as:
“One interface, multiple methods.”
So, the method signature is the same in all classes, but the actual behavior depends on the
subclass object.
Why Polymorphism Is Essential
Polymorphism is important in OOP because it allows:
 A general superclass to define a set of methods that all subclasses must share.
 Each subclass to implement these methods in a specialized way based on their needs.
This creates a structure where the superclass provides what is common, while subclasses
provide what is specific.
Hierarchy and Specialization
Classes in OOP form a hierarchy:
Superclass → Subclass → More specialized subclass
 The superclass contains all the general features.
 Subclasses become progressively more specialized.
 Subclasses can:
o directly use what the superclass provides
o override methods to add their own specific behavior
This allows subclasses to be flexible while still following a consistent interface
defined by the superclass.
Why Polymorphism Makes Code Powerful
Dynamic run-time polymorphism is powerful because:
 You can reuse existing code without modification.
 You can create new subclasses and existing programs will still work with them.
 Libraries can call methods on new objects without being recompiled.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 58


OOPs with JAVA(M23BCS306B)
Module – 3

 It makes your code cleaner, more modular, and easier to extend.


Example:
If a library expects an object of type Shape, you can create new classes like Triangle, Pentagon,
etc., and the library will still work because it relies on polymorphism.
Applying Method Overriding
Let’s look at a more practical example that uses method overriding. The following program
creates a superclass called Figure that stores the dimensions of a two-dimensional object. It
also defines a method called area( ) that computes the area of an object. The program derives
two subclasses from Figure. The first is Rectangle and the second is Triangle. Each of these
subclasses overrides area( ) so that it returns the area of a rectangle and a triangle, respectively.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 59


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 60


OOPs with JAVA(M23BCS306B)
Module – 3

Through the dual mechanisms of inheritance and run-time polymorphism, it is possible to


define one consistent interface that is used by several different, yet related, types of objects. In
this case, if an object is derived from Figure, then its area can be obtained by calling area( ).
The interface to this operation is the same no matter what type of figure is being used. Using
Abstract Classes
Need for Partial Implementation in Superclass
 Sometimes a superclass can define the general structure, but cannot give full
implementation for all methods.
 Example: In a Figure class, the method area() has no meaningful generic formula.
Why This Happens
 The superclass knows what all shapes have in common (dimensions), but not how
each shape computes its area.
 Some methods simply cannot have a common implementation at the superclass level.
Incomplete or Placeholder Methods Are Not Ideal
 In earlier examples, area() printed a warning (“undefined”).
 This is not a safe or meaningful design for large software systems.
 We need a mechanism to force subclasses to implement certain methods.
Java’s Solution → Abstract Methods
 A method with no body and meant only to be overridden is declared as abstract.
 Syntax:
abstract returnType methodName();
 Example:
abstract double area();
Subclasser Responsibility
 Abstract methods must mandatory be overridden by subclasses.
 A subclass cannot ignore an abstract method.
 This ensures the subclass has meaningful behavior.
Abstract Class
 A class containing one or more abstract methods must be declared abstract.
 Syntax:
abstract class Figure {
abstract double area();

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 61


OOPs with JAVA(M23BCS306B)
Module – 3

}
 You cannot create an object of an abstract class.
Purpose of Abstract Classes
 Define the template or general structure
 Force subclasses to provide specific implementations
 Support polymorphism with partially implemented superclasses
Points (Exam-Friendly)
 Abstract method → declared, not implemented.
 Abstract class → cannot be instantiated.
 Subclasses → must override all abstract methods, unless they are also abstract.
 Used when the superclass cannot fully implement a method.
 Enables run-time polymorphism with compulsory overriding.
abstract type name(parameter-list);
As you can see, no method body is present.
Any class that contains one or more abstract methods must also be declared abstract. To declare
a class abstract, you simply use the abstract keyword in front of the class keyword at the
beginning of the class declaration. There can be no objects of an abstract class. That is, an
abstract class cannot be directly instantiated with the new operator. Such objects would be
useless, because an abstract class is not fully defined. Also, you cannot declare abstract
constructors or abstract static methods. Any subclass of an abstract class must either
implement all of the abstract methods in the superclass or be declared abstract itself.
Here is a simple example of a class with an abstract method, followed by a class which
implements that method:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 62


OOPs with JAVA(M23BCS306B)
Module – 3

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( ). This is perfectly acceptable. Abstract classes can include as much
implementation as they see fit.
Although abstract classes cannot be used to instantiate objects, they can be used to
create object references, because Java’s approach to run-time polymorphism is implemented
through the use of superclass references. Thus, it must be possible to create a reference to an
abstract class so that it can be used to point to a subclass object. You will see this feature put to
use in the next example:
Using an abstract class, you can improve the Figure class shown earlier. Since there is
no meaningful concept of area for an undefined two-dimensional figure, the following version
of the program declares area( ) as abstract inside Figure. This, of course, means that all classes
derived from Figure must override area( ).

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 63


OOPs with JAVA(M23BCS306B)
Module – 3

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 64


OOPs with JAVA(M23BCS306B)
Module – 3

Using final with Inheritance


The keyword final has three uses. First, it can be used to create the equivalent of a named
constant. The other two uses of final apply to inheritance. Both are examined here.
Using final to Prevent Overriding
While method overriding is one of Java’s most powerful features, there will be times when you
will want to prevent it from occurring. To disallow a method from being overridden, specify
final as a modifier at the start of its declaration.
Methods declared as final cannot be overridden. The following fragment illustrates final:

Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to do so, a


compile-time error will result.
 A method declared with the keyword final cannot be overridden by any subclass.
final methods can improve performance
 Because they cannot be overridden, the compiler knows exactly which method will
run.
 This allows certain optimizations.
Inlining of final methods
o For very small final methods, the compiler may inline them.
o Inlining means:
The JVM copies the method’s bytecode directly into the caller’s code instead of
making a method call.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 65


OOPs with JAVA(M23BCS306B)
Module – 3

o Result:

 Faster execution
 No overhead of calling a separate method
Why only final methods can be inlined
 Java normally uses late binding (run-time method resolution) for overridden methods.
 Since most methods can be overridden, the JVM cannot decide at compile time which
version will run.
 But with final methods, overriding is impossible → so the exact method is known
earlier.
Late binding (run-time binding)
 Default behavior in Java.
 The JVM decides at run time which method to call.
 Necessary because subclass methods may override superclass methods.
Early binding (compile-time binding)
 Possible only when the method is final, static, or private.
 The compiler resolves the method call at compile time.
 Faster than late binding.
Summary
 final methods cannot be overridden, so the JVM knows exactly which method to call.
 This enables early binding, meaning the compiler can sometimes inline the method.
 Inlining removes call overhead → performance improvement.
 Normal methods use late binding because they may be overridden.
Using final to Prevent Inheritance
Purpose of a final class
 A final class cannot be inherited.
 This means no subclass can extend it
final class
 To prevent modification of critical classes.
 To maintain security, stability, or design integrity.
 Common example: The Java String class is final.
Cannot be both abstract and final
 An abstract class requires subclasses (because it is incomplete).

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 66


OOPs with JAVA(M23BCS306B)
Module – 3

 A final class forbids subclasses.


 Therefore, a class cannot be abstract + final at the same time.
(It would contradict itself logically.)
When final classes are useful
 When you want a class to be fully functional and unchangeable.
 When inheritance could cause errors or misuse.
 When implementing immutable objects.
Here is an example of a final class:

As the comments imply, it is illegal for B to inherit A since A is declared as final.


NOTE Beginning with JDK 17, the ability to seal a class was added to Java. Sealing offers
fine-grained control over inheritance.
Local Variable Type Inference and Inheritance
JDK 10 added local variable type inference to the Java language, which is supported by the
context-sensitive keyword var. It is important to have a clear understanding of how type
inference works within an inheritance hierarchy. Recall that a superclass reference can refer to
a derived class object, and this feature is part of Java’s support for polymorphism. However, it
is critical to remember that when using local variable type inference, the inferred type of a
variable is based on the declared type of its initializer. Therefore, if the initializer is of the
superclass type, that will be the inferred type of the variable. It does not matter if the actual
object being referred to by the initializer is an instance of a derived class. For example, consider
this program:

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 67


OOPs with JAVA(M23BCS306B)
Module – 3

}
In the program, a hierarchy is created that consists of three classes, at the top of which is
MyClass. FirstDerivedClass is a subclass of MyClass, and SecondDerivedClass is a
subclass of FirstDerivedClass. The program then uses type inference to create three variables,
called mc, mc2, and mc3, by calling getObj( ). The getObj( ) method has a return type of
MyClass (the superclass) but returns objects of type MyClass, FirstDerivedClass, or
SecondDerivedClass, depending on the argument that it is passed. As the output shows, the
inferred type is determined by the return type of getObj( ), not by the actual type of the object
obtained. Thus, all three variables will be of type MyClass.

[Link] | DEPARTMENT OF CSE (IOT & CYBER SECURITY) 68

You might also like