Polymorphism
Polymorphism is a core concept in object-oriented programming (OOP) that allows methods to perform different tasks based on the object that invokes them. In Java, polymorphism enables you to define a single interface or method and have multiple implementations for it, depending on the object type.
Types of Polymorphism in Java
There are two main types of polymorphism in Java:
- Compile-Time Polymorphism (Static Binding)
- Run-Time Polymorphism (Dynamic Binding)
Polymorphism
Polymorphism allows methods to perform different functions based on the object that it is called on.
Compile-Time Polymorphism (Method Overloading)
This occurs when multiple methods have the same name but differ in their parameters.
Example:
class MathOperations {
// Method to add two integers
public int add(int a, int b) {
return a + b;
}
// Method to add two doubles
public double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
MathOperations mathOp = new MathOperations();
System.out.println(mathOp.add(3, 4)); // Output: 7 (integer addition)
System.out.println(mathOp.add(3.5, 4.5)); // Output: 8.0 (double addition)
}
}
Explanation:
- The
MathOperationsclass has twoaddmethods: one for integers and one for doubles. The correct method is determined at compile time based on the arguments provided.
Run-Time Polymorphism (Method Overriding)
This occurs when a subclass provides a specific implementation of a method that is already defined in its superclass.
Example:
class Animal {
public void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // Output: Bark
myCat.makeSound(); // Output: Meow
}
}
Explanation:
- The
Animalclass has a methodmakeSound. TheDogandCatclasses override this method to provide their specific sounds. - When
makeSoundis called onmyDogormyCat, the correct method is determined at runtime based on the object type.
Abstract Classes and Functions
An abstract class cannot be instantiated on its own and often contains abstract methods that subclasses must implement.
Example:
abstract class Shape {
// Abstract method for calculating area
public abstract double area();
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
class Square extends Shape {
private double side;
public Square(double side) {
this.side = side;
}
@Override
public double area() {
return side * side;
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new Circle(5);
Shape square = new Square(4);
System.out.println("Circle Area: " + circle.area()); // Output: Circle Area: 78.53981633974483
System.out.println("Square Area: " + square.area()); // Output: Square Area: 16.0
}
}
Explanation:
- The
Shapeclass is abstract and defines an abstract methodarea. - The
CircleandSquareclasses implement theareamethod. - The main method creates instances of
CircleandSquareand calls theirareamethods.
Abstract Functions Practical Example
This example demonstrates how abstract methods enforce a contract for subclasses.
Example:
abstract class Vehicle {
// Abstract method
public abstract void move();
}
class Car extends Vehicle {
@Override
public void move() {
System.out.println("Driving on the road");
}
}
class Boat extends Vehicle {
@Override
public void move() {
System.out.println("Sailing on water");
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
Vehicle boat = new Boat();
car.move(); // Output: Driving on the road
boat.move(); // Output: Sailing on water
}
}
Explanation:
- The
Vehicleclass defines an abstract methodmove. - The
CarandBoatclasses implementmoveto provide specific behaviors. - The main method creates instances of
CarandBoatand calls theirmovemethods.
Interfaces
An interface defines a contract with methods that classes must implement.
Example:
interface SoundMaker {
void makeSound();
}
class Dog implements SoundMaker {
@Override
public void makeSound() {
System.out.println("Bark");
}
}
class Cat implements SoundMaker {
@Override
public void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
SoundMaker dog = new Dog();
SoundMaker cat = new Cat();
dog.makeSound(); // Output: Bark
cat.makeSound(); // Output: Meow
}
}
Explanation:
- The
SoundMakerinterface defines a methodmakeSound. - The
DogandCatclasses implement themakeSoundmethod. - The main method creates instances of
DogandCatand calls theirmakeSoundmethods.
Practical Uses of Interfaces
Interfaces allow different classes to implement the same methods, facilitating code organization and polymorphism.
Example:
public class Main {
public static void animalSound(SoundMaker animal) {
animal.makeSound();
}
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
animalSound(dog); // Output: Bark
animalSound(cat); // Output: Meow
}
}
Explanation:
- The
animalSoundmethod accepts any object that implements theSoundMakerinterface. - This promotes loose coupling and flexibility in code design.
Interfaces Focused View
A focused view emphasizes how interfaces standardize method implementations across classes.
Example:
class Bird implements SoundMaker {
@Override
public void makeSound() {
System.out.println("Chirp");
}
}
public class Main {
public static void main(String[] args) {
SoundMaker bird = new Bird();
bird.makeSound(); // Output: Chirp
}
}
Explanation:
- The
Birdclass implements theSoundMakerinterface. - All classes that implement the interface can be treated the same way, regardless of their actual type.
Interfaces Different Implementation
Different classes can implement the same interface in distinct ways, showcasing polymorphism.
Example:
class Car implements SoundMaker {
@Override
public void makeSound() {
System.out.println("Vroom");
}
}
public class Main {
public static void main(String[] args) {
SoundMaker car = new Car();
car.makeSound(); // Output: Vroom
}
}
Explanation:
- The
Carclass provides a different implementation ofmakeSound. - The
carobject demonstrates polymorphism by being treated as aSoundMaker.
Interfaces Unrelated Inheritance
Interfaces enable classes from different hierarchies to implement the same methods, allowing interchangeable usage.
Example:
class Truck implements SoundMaker {
@Override
public void makeSound() {
System.out.println("Honk");
}
}
public class Main {
public static void main(String[] args) {
SoundMaker truck = new Truck();
truck.makeSound(); // Output: Honk
}
}
Explanation:
- The
Truckclass implements theSoundMakerinterface. - Even though
Truckis unrelated toDogandCat, it can be used in the same context, allowing for flexibility.
Summary
- Polymorphism enables methods to act differently based on the object type.
- Abstract Classes and Functions provide a template for subclasses to follow.
- Interfaces define contracts for classes to implement, allowing for uniform behavior across unrelated classes.