** What is the final keyword in Java?**

The final keyword in Java is used to restrict changes. Depending on how it’s used, it can:

  • Prevent variable reassignment
  • Prevent method overriding
  • Prevent class inheritance
  1. Final Variable – cannot be reassigned.
final int x = 10;
x = 20; // ❌ Error: cannot assign a value to final variable
  1. Final Method – cannot be overridden by a subclass.
class Animal {
    final void sound() {
        System.out.println("Animal makes sound");
    }
}

class Dog extends Animal {
    // void sound() {  // ❌ Error
    //     System.out.println("Dog barks");
    // }
}

3. Final Class – cannot be inherited.

final class Vehicle {
    void run() {
        System.out.println("Vehicle is running");
    }
}

// class Car extends Vehicle {  // ❌ Error
// }

What is polymorphism?
Polymorphism in Java is one of the core concepts of Object-Oriented Programming (OOP). The word "polymorphism" means "many forms", and in Java, it allows objects to behave in multiple ways depending on how they are used.

Why is Polymorphism Important?

  • Promotes code reusability.
  • Helps in code flexibility and maintainability.
  • Supports dynamic method binding, which is powerful in large applications.

Types of Polymorphism in Java:
1. Compile-time Polymorphism (Method Overloading)

  • This occurs when multiple methods in the same class have the same name but different parameters (type, number, or order).
  • The method that gets called is determined at compile time.
class MathOperations {
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }
}

2. Runtime Polymorphism (Method Overriding)

  • This occurs when a subclass provides a specific implementation of a method that is already defined in its superclass.
  • The method call is determined at runtime based on the object type.
class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    void sound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal a;

        a = new Dog();  // runtime decision
        a.sound();      // Output: Dog barks

        a = new Cat();  
        a.sound();      // Output: Cat meows
    }
}