JAVA - POLYMORPHISM
Polymorphism in Java: A Comprehensive Guide Polymorphism is one of the four fundamental principles of object-oriented programming (OOP) in Java, along with encapsulation, inheritance, and abstraction. It allows objects to take on many forms and enables flexible, reusable code. Types of Polymorphism in Java 1. Compile-Time Polymorphism (Static Polymorphism) Method Overloading: Multiple methods with the same name but different parameters in the same class. class Calculator { // Method to add two integers int add(int a, int b) { return a + b; } // Overloaded method to add three integers int add(int a, int b, int c) { return a + b + c; } // Overloaded method to add doubles double add(double a, double b) { return a + b; } } Key characteristics: Determined at compile time Based on method signature (name + parameters) Return type alone doesn't differentiate overloaded methods 2. Runtime Polymorphism (Dynamic Polymorphism) Method Overriding: Subclass provides specific implementation of a method already defined in its superclass. class Animal { void makeSound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { @Override void makeSound() { System.out.println("Dog barks"); } } class Cat extends Animal { @Override void makeSound() { System.out.println("Cat meows"); } } Key characteristics: Determined at runtime Requires inheritance Uses method overriding with same signature as parent class Annotated with @Override (recommended) Polymorphism in Action public class Main { public static void main(String[] args) { Animal myAnimal = new Animal(); // Animal reference, Animal object Animal myDog = new Dog(); // Animal reference, Dog object Animal myCat = new Cat(); // Animal reference, Cat object myAnimal.makeSound(); // Output: Animal makes a sound myDog.makeSound(); // Output: Dog barks (runtime polymorphism) myCat.makeSound(); // Output: Cat meows (runtime polymorphism) } } Key Concepts in Polymorphism 1. Upcasting Creating a parent class reference variable for child class objects. Animal animal = new Dog(); // Upcasting 2. Downcasting Converting a parent class reference back to child class type. Animal animal = new Dog(); Dog dog = (Dog) animal; // Downcasting 3. The instanceof Operator Used to check the actual type of an object before downcasting. if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.bark(); } Polymorphism with Interfaces Java interfaces provide another powerful way to implement polymorphism: interface Shape { void draw(); } class Circle implements Shape { @Override public void draw() { System.out.println("Drawing Circle"); } } class Square implements Shape { @Override public void draw() { System.out.println("Drawing Square"); } } public class Main { public static void main(String[] args) { Shape shape1 = new Circle(); // Polymorphic reference Shape shape2 = new Square(); // Polymorphic reference shape1.draw(); // Output: Drawing Circle shape2.draw(); // Output: Drawing Square } } Benefits of Polymorphism Code Reusability: Write more generic and reusable code Flexibility: Easily extend and modify existing code Maintainability: Reduce code complexity and improve organization Extensibility: Add new functionality without modifying existing code Interface-based Programming: Work with abstractions rather than concrete implementations Practical Applications Collections Framework: List list = new ArrayList(); // Polymorphism Method Parameters: public void printArea(Shape shape) { // Accepts any Shape implementation System.out.println(shape.calculateArea()); } Factory Pattern: public class AnimalFactory { public Animal getAnimal(String type) { if ("dog".equalsIgnoreCase(type)) { return new Dog(); } else if ("cat".equalsIgnoreCase(type)) { return new Cat(); } return null; } } Polymorphism Rules in Java Method overriding cannot reduce visibility (can't override public with private) Final methods cannot be overridden Static methods cannot be overridden (method hiding instead) Private methods are not polymorphic (not visible to subclasses) Constructors cannot be polymorphic Understanding polymorphism is essential for writing flexible, maintainable Java applications that leverage object-oriented principles effectively.

Polymorphism in Java: A Comprehensive Guide
Polymorphism is one of the four fundamental principles of object-oriented programming (OOP) in Java, along with encapsulation, inheritance, and abstraction. It allows objects to take on many forms and enables flexible, reusable code.
Types of Polymorphism in Java
1. Compile-Time Polymorphism (Static Polymorphism)
Method Overloading: Multiple methods with the same name but different parameters in the same class.
class Calculator {
// Method to add two integers
int add(int a, int b) {
return a + b;
}
// Overloaded method to add three integers
int add(int a, int b, int c) {
return a + b + c;
}
// Overloaded method to add doubles
double add(double a, double b) {
return a + b;
}
}
Key characteristics:
- Determined at compile time
- Based on method signature (name + parameters)
- Return type alone doesn't differentiate overloaded methods
2. Runtime Polymorphism (Dynamic Polymorphism)
Method Overriding: Subclass provides specific implementation of a method already defined in its superclass.
class Animal {
void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Cat meows");
}
}
Key characteristics:
- Determined at runtime
- Requires inheritance
- Uses method overriding with same signature as parent class
- Annotated with
@Override
(recommended)
Polymorphism in Action
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // Animal reference, Animal object
Animal myDog = new Dog(); // Animal reference, Dog object
Animal myCat = new Cat(); // Animal reference, Cat object
myAnimal.makeSound(); // Output: Animal makes a sound
myDog.makeSound(); // Output: Dog barks (runtime polymorphism)
myCat.makeSound(); // Output: Cat meows (runtime polymorphism)
}
}
Key Concepts in Polymorphism
1. Upcasting
Creating a parent class reference variable for child class objects.
Animal animal = new Dog(); // Upcasting
2. Downcasting
Converting a parent class reference back to child class type.
Animal animal = new Dog();
Dog dog = (Dog) animal; // Downcasting
3. The instanceof
Operator
Used to check the actual type of an object before downcasting.
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
}
Polymorphism with Interfaces
Java interfaces provide another powerful way to implement polymorphism:
interface Shape {
void draw();
}
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Circle");
}
}
class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing Square");
}
}
public class Main {
public static void main(String[] args) {
Shape shape1 = new Circle(); // Polymorphic reference
Shape shape2 = new Square(); // Polymorphic reference
shape1.draw(); // Output: Drawing Circle
shape2.draw(); // Output: Drawing Square
}
}
Benefits of Polymorphism
- Code Reusability: Write more generic and reusable code
- Flexibility: Easily extend and modify existing code
- Maintainability: Reduce code complexity and improve organization
- Extensibility: Add new functionality without modifying existing code
- Interface-based Programming: Work with abstractions rather than concrete implementations
Practical Applications
- Collections Framework:
List<String> list = new ArrayList<>(); // Polymorphism
- Method Parameters:
public void printArea(Shape shape) { // Accepts any Shape implementation
System.out.println(shape.calculateArea());
}
- Factory Pattern:
public class AnimalFactory {
public Animal getAnimal(String type) {
if ("dog".equalsIgnoreCase(type)) {
return new Dog();
} else if ("cat".equalsIgnoreCase(type)) {
return new Cat();
}
return null;
}
}
Polymorphism Rules in Java
- Method overriding cannot reduce visibility (can't override public with private)
- Final methods cannot be overridden
- Static methods cannot be overridden (method hiding instead)
- Private methods are not polymorphic (not visible to subclasses)
- Constructors cannot be polymorphic
Understanding polymorphism is essential for writing flexible, maintainable Java applications that leverage object-oriented principles effectively.