Copy of Session 12 - Methods - Part 2
Copy of Session 12 - Methods - Part 2
THROUGH JAVA
UNIT - II
1. Recursive Methods
In Java, recursion is a process in which a method calls itself directly or indirectly. The method
that performs this self-call is known as a recursive method. Recursive algorithms are powerful
tools for solving problems that can be divided into similar sub-problems. Examples of problems
solved using recursion include the Towers of Hanoi, tree traversals (Inorder, Preorder,
Postorder), and Depth-First Search (DFS) of graphs.
In a recursive program, the base case provides the solution for the simplest instance of the
problem and serves as a stopping point for the recursion. The solution to more complex
instances of the problem is expressed in terms of smaller, simpler sub-problems.
int fact(int n) {
if (n <= 1) // base case
return 1;
else
return n * fact(n - 1); // recursive case
}
In this example, the base case is defined as ( n \leq 1 ), returning 1. For larger values of ( n ),
the method recursively calls itself with ( n-1 ) until the base case is reached.
Working of Recursion:
The essence of recursion is to solve a problem by breaking it down into smaller instances of the
same problem and combining the results. For instance, to compute the factorial of ( n ), if you
know the factorial of ( n-1 ), you can compute ( n! ) as ( n \times (n-1)! ). The base case for the
factorial problem is ( n = 0 ), where the factorial is defined as 1.
The factorial of a number ( N ) is calculated as the product of all positive integers from 1 to ( N ).
Below is a Java implementation of the factorial calculation using recursion:
if (n == 1) // Base case
return 1;
result = fact(n - 1) * n; // Recursive case
return result;
}
}
// Driver Class
class Recursion {
// Main function
public static void main(String[] args) {
GFG f = new GFG();
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
2. Fibonacci Series
Fibonacci Numbers are the integer sequence where Fib(N) = Fib(N-2) + Fib(N-1). Below is an
example to find 3,4,5.
class GFG {
// Main function
public static void main(String[] args) {
System.out.println("Fibonacci of " + 3 + " is " + Fib(3));
System.out.println("Fibonacci of " + 4 + " is " + Fib(4));
System.out.println("Fibonacci of " + 5 + " is " + Fib(5));
}
}
Output:
Fibonacci of 3 is 2
Fibonacci of 4 is 3
Fibonacci of 5 is 5
Stack Overflow Error:
If the base case is not defined properly, the recursion may continue indefinitely, causing a stack
overflow error. For example:
int fact(int n) {
// Incorrect base case (it may cause stack overflow).
if (n == 100)
return 1;
else
return n * fact(n - 1);
}
If fact(10) is called, it will call fact(9), fact(8), and so on, but will never reach 100. This
will eventually lead to a stack overflow error as the memory is exhausted.
When a function is called, memory is allocated on the stack for that function's local variables
and state. For recursive calls, each function call creates a new stack frame. Each call has its
own set of local variables. Once the base case is reached, the function returns its value, and the
stack frames are de-allocated, allowing the previous calls to complete.
Example of Recursion:
3 2 1 1 2 3
Explanation:
When printFun(3) is called, it prints 3, then calls printFun(2), which prints 2, and so forth.
After reaching the base case, the function starts returning, printing the numbers in reverse order
as it returns to the previous calls.
- Provides a clean and simple way to write code for problems that naturally fit a recursive
approach.
- Particularly useful for problems like tree traversals and the Tower of Hanoi, where the
recursive approach mirrors the problem structure.
Note: Both recursive and iterative solutions have the same problem-solving capabilities. Any
problem that can be solved recursively can also be solved iteratively, and vice versa.
Do It Yourself
1. Write a recursive method in Java that calculates the sum of all natural numbers up to
nnn. For example, if n=5n = 5n=5, the method should return 1+2+3+4+51 + 2 + 3 + 4 +
51+2+3+4+5. Call this method from the main method and print the result for n=5n =
5n=5.
2. Create a recursive method in Java to calculate xxx raised to the power of yyy (i.e.,
xyx^yxy). For example, if x=2x = 2x=2 and y=3y = 3y=3, the method should return 8.
Test this method with x=2x = 2x=2 and y=3y = 3y=3.
3. Create a recursive method gcd(int a, int b) that calculates the greatest common
divisor of two integers aaa and bbb. For example, gcd(48, 18) should return 6.
Quiz
Here are five multiple-choice questions (MCQs) on recursive methods in Java, along with their
answers:
A) 3
B) 6
C) 9
D) 12
Answer: B) 6
Answer: C) Recursive methods must always have a base case to avoid infinite
recursion
2. Nesting of Methods
Syntax
Java does not allow declaring a method within another method directly (as in some other
programming languages like Python). However, nesting of method calls is allowed, where one
method calls another, forming a hierarchy of method executions.
General Syntax:
class ClassName {
// Method 1
void method1() {
// Method body
}
// Method 2
void method2() {
// Method1 is called inside Method2
method1();
}
}
In this example, method2() calls method1() within its body. This kind of nesting helps in
organizing functionality and code reusability.
Example:
class BankAccount {
double balance;
Output:
Deposit of $200 successful.
Checking balance...
Withdrawal of $100 successful.
Deducting transaction charges...
Explanation:
- In this example, withdraw() method calls both checkBalance() and
deductCharges() to check the account balance and deduct charges. These methods
are "nested" within the withdraw() method.
- This example simulates real-time banking operations where multiple steps need to be
performed together, making method nesting an effective way to organize related tasks.
Key Points
1. Improved Code Modularity: Nesting methods breaks down larger, complex tasks into
smaller, reusable methods. Each method performs a specific task, improving code
readability and reusability.
3. Flexibility in Design: Using nested methods allows you to modify one method's
functionality without impacting others. For example, if the transaction charges change,
the deductCharges() method can be updated without altering the other methods.
4. Real-Time Usage: In real-world applications like banking, online shopping, or hotel
booking, method nesting is essential to manage sequences of operations in a clean and
organized manner.
Nesting methods in Java is a useful technique for organizing code and promoting reuse. While
Java does not allow the direct declaration of methods inside other methods, it supports method
nesting via calls, allowing one method to invoke others, making code simpler and more
maintainable in complex systems.
Do It Yourself
1. Implement a program that converts between Celsius, Fahrenheit, and Kelvin using
nested conversion methods.
2. Write a program that adds items to a cart, calculates the total, and applies discounts
using nested method calls.
3. Design a program where nested methods check book availability, issue books, and
calculate overdue fines.
4. Create a program that calculates the final grade using nested methods to compute
marks from assignments, exams, and projects.
Quiz
Answer: B) Nested classes can access all members of the outer class, including private
ones
class Outer {
class Inner {
void show() {
System.out.println("Inside Inner class");
}
}
}
class Test {
public static void main(String[] args) {
// Which of the following is the correct way to instantiate Inner class?
}
}
A) Inner i = new Inner();
B) Outer.Inner i = new Outer.Inner();
C) Outer.Inner i = new Outer().new Inner();
D) Outer.Inner i = new Inner();
3. Which type of nested class can access only static members of the outer class?
A) Static nested class
B) Non-static inner class
C) Anonymous inner class
D) Local inner class
4. Which of the following is a valid reason for using nested Java classes?
A) To reduce the visibility of a class
B) To create multiple objects of the outer class
C) To avoid memory leaks
D) To organize classes that are used only by the outer class
Answer: D) To organize classes that are used only by the outer class
class Outer {
private int x = 10;
class Inner {
void display() {
System.out.println(x);
}
}
}
Answer: D) 10
Answer: C) Static nested classes can be instantiated without an object of the outer
class
4. Method Overriding
- Same Method Signature: The overriding method must have the same name, parameter
list, and return type (or subtype) as the method in the superclass.
- Access Modifiers: The access level of the overriding method can be the same or more
accessible than the method in the superclass (e.g., protected can be overridden as
public).
- Method Bodies: The implementation of the method in the subclass provides the specific
behavior.
// Subclass
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks");
}
}
// Driver Class
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
myAnimal.makeSound(); // Output: Animal makes a sound
- An overriding method can have the same or more permissive access level
compared to the method in the superclass. For instance, if the superclass
method is protected, it can be overridden with protected or public, but not
with private.
class Parent {
protected void display() {
System.out.println("Display from Parent");
}
}
class Parent {
final void display() {
System.out.println("Final display from Parent");
}
}
class Parent {
static void display() {
System.out.println("Static display from Parent");
}
}
class Parent {
private void display() {
System.out.println("Private display from Parent");
}
}
- From Java 5 onwards, the return type of the overriding method can be a subtype
of the return type declared in the superclass.
class Parent {
public Number getNumber() {
return 1;
}
}
- The super keyword can be used to call methods from the superclass within the
overriding method.
class Parent {
void show() {
System.out.println("Parent's show()");
}
}
3. Write a base class Shape with a method draw(). Create subclasses Circle and
Rectangle that override the draw() method to provide specific drawing behavior.
4. Implement a class Animal with a method eat(). Create a subclass Cat that overrides
the eat() method to provide a specific eating behavior.
5. Create a class Bird with a method fly(). Define a subclass Parrot that overrides
fly() to provide a detailed implementation of how a parrot flies.
Quiz
class A {
void show() {
System.out.println("A");
}
}
class B extends A {
void show() {
System.out.println("B");
}
}
Answer: B) B
class Parent {
static void display() {
System.out.println("Parent display");
}
}
Location Occurs within the same class. Involves two classes with an
inheritance relationship.
Method Signature Methods must have the same Methods must have the same
name but different signatures name, signature, and return type.
(parameter lists).
Return Type The return type can be the same The return type must be the
or different. Parameters must same or co-variant.
change.
Binding Type Uses static binding (compile- Uses dynamic binding (run-time).
time).
Private/Final Methods Private and final methods can be Private and final methods cannot
overloaded. be overridden.
Method Overloading
Method Overloading allows multiple methods in the same class to share the same name but
differ in their parameter lists. It's a type of compile-time polymorphism.
void eatAsAnimal() {
super.eat();
}
}
class MethodOverridingEx {
public static void main(String args[]) {
Dog dog = new Dog();
Animal animal = new Animal();
// Polymorphism
Animal animalDog = new Dog();
animalDog.eat(); // Calls Dog's eat method due to dynamic binding
Dog is eating.
Animal is eating.
Dog is eating.
Animal is eating.
Explanation:
● The eat() method is overridden in the Dog class, providing its own implementation
while the parent Animal class has its own.
● The base class method can be called using the super keyword within the subclass.
Key Takeaways:
1. Final Methods
When a method is declared final, subclasses cannot override it. This is typically used to prevent
modification of crucial functionality in derived classes.
2. Static Methods
A static method in Java belongs to the class rather than to any specific instance (object) of
that class. This means static methods can be called without creating an object of the class.
Object/Class Associated with object instances. Associated with the class itself.
Usage Used to prevent changes to Used for utility methods that don’t
method behavior. depend on object state.
Instance Access Can access instance variables Cannot access instance variables
Aspect final Method static Method
● Use final methods when you want to prevent any modifications to the method’s
behavior in subclasses.
● Use static methods when the method’s functionality is tied to the class as a whole and
does not rely on object instances.
Do It Yourself
1. Write a Java program that demonstrates the use of the final keyword with methods.
Create a parent class with a final method and attempt to override it in the child class.
Explain why the program does or does not compile.Show a compilation error for the final
method being overridden and explain the error.
2. Create a Java program with a class that has both instance and static methods. Call the
static method without creating an instance of the class. Explain how static methods differ
from instance methods in terms of memory and access.
3. Write a Java program that declares a final method and a static method within the
same class. Inside the static method, attempt to modify a final variable. Explain why the
program does or does not allow modification of the final variable inside the static method
Quiz
Answer: A) Static methods can be called without creating an instance of the class.
3. Given the following code, what will happen when the program is compiled?
class A {
public final void display() {
System.out.println("Final method in Class A");
}
}
class B extends A {
public void display() {
System.out.println("Trying to override final method");
}
}
A) The code will run and print "Trying to override final method."
B) The code will run and print "Final method in Class A."
C) The program will fail to compile with an error.
D) The code will throw a runtime exception.
4. Which of the following statements is false regarding the static and final keywords
in methods?
A) A static method belongs to the class rather than to any specific object.
B) A final method cannot be overridden by a subclass.
C) A static method can be overridden in the subclass.
D) A final method can be called from the subclass but cannot be modified.
class Test {
static int count = 0;
Test() {
count++;
}
}
Answer: D) 3
class MyClass {
static void display() {
System.out.println("Static method called");
}
}
Answer: C) The static method can be called using both the class name and the object.
References
Recursive methods - Recursion in Java Full Tutorial - How to Create Recursive Methods
Nesting of methods - Java-70- Nesting of Methods in Java || Java Programming
Method overriding - #52 Method Overriding in Java
Method overloading Vs Method overriding - DIFFERENCES BETWEEN METHOD
OVERLOADING AND OVERRIDING - JAVA PROGRAMMING
Final and static methods - #57 Final keyword in java#4.6 Java Tutorial | Static Keyword
End of Session - 12