Java Polymorphism
One interface, multiple implementations
🎠What is Polymorphism?
Polymorphism means "many forms." It allows objects of different classes to be treated as objects of a common parent class while maintaining their specific behaviors.
// Same method call, different behaviors
Animal animal1 = new Dog();
Animal animal2 = new Cat();
animal1.makeSound(); // Output: Woof!
animal2.makeSound(); // Output: Meow!
Output:
Woof!
Meow!
Key Polymorphism Concepts
Method Overriding
Child classes provide specific implementations
@Override
public void draw() {
// Specific implementation
}
Runtime Binding
Method called is determined at runtime
Shape s = new Circle();
s.draw(); // Circle's draw()
Common Interface
Same method signature, different behavior
public void makeSound() {
// Each animal sounds different
}
Dynamic Method
Actual method depends on object type
Animal a = getRandomAnimal();
a.move(); // Different for each animal
🔹 Complete Polymorphism Example
Here's how polymorphism works in practice:
// Parent class
abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
// Abstract method - must be overridden
public abstract void makeSound();
// Concrete method - can be overridden
public void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child classes
class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says: Woof! Woof!");
}
}
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says: Meow! Meow!");
}
}
class Cow extends Animal {
public Cow(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says: Moo! Moo!");
}
}
// Demonstrating polymorphism
public class PolymorphismDemo {
public static void main(String[] args) {
// Array of different animals
Animal[] animals = {
new Dog("Buddy"),
new Cat("Whiskers"),
new Cow("Bessie")
};
// Same method call, different behaviors
for(Animal animal : animals) {
animal.makeSound(); // Polymorphic behavior
animal.sleep(); // Inherited behavior
}
}
}
Output:
Buddy says: Woof! Woof!
Buddy is sleeping
Whiskers says: Meow! Meow!
Whiskers is sleeping
Bessie says: Moo! Moo!
Bessie is sleeping
🔹 Types of Polymorphism
🔸 Runtime Polymorphism (Method Overriding)
class Shape {
public void draw() {
System.out.println("Drawing a shape");
}
}
class Circle extends Shape {
@Override
public void draw() {
System.out.println("Drawing a circle");
}
}
// Usage
Shape shape = new Circle();
shape.draw(); // Output: "Drawing a circle"
🔸 Compile-time Polymorphism (Method Overloading)
class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
}
// Usage
Calculator calc = new Calculator();
calc.add(5, 3); // Calls int version
calc.add(5.5, 3.2); // Calls double version
calc.add(1, 2, 3); // Calls three-parameter version
🔹 Benefits of Polymorphism
- Code Reusability: Write code once, work with multiple types
- Flexibility: Easy to add new classes without changing existing code
- Maintainability: Changes in child classes don't affect parent code
- Extensibility: New implementations can be added easily
// Polymorphic method - works with any Animal
public static void makeAnimalSound(Animal animal) {
animal.makeSound(); // Calls appropriate method based on actual type
}
// Can be called with any Animal subclass
makeAnimalSound(new Dog("Rex"));
makeAnimalSound(new Cat("Fluffy"));
makeAnimalSound(new Cow("Moo-bert"));