WikiGalaxy

Personalize

Java Polymorphism

Introduction to Polymorphism

Polymorphism in Java allows objects to be treated as instances of their parent class. It is one of the core concepts of OOP, enabling a single action to behave differently based on the object that it is acting upon.


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 TestPolymorphism {
    public static void main(String[] args) {
        Animal a;
        a = new Dog();
        a.sound();
        a = new Cat();
        a.sound();
    }
}
    

Console Output:

Dog barks

Cat meows

Method Overriding

Understanding Method Overriding

Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. This is a key aspect of achieving runtime polymorphism.


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

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

public class TestOverride {
    public static void main(String[] args) {
        Vehicle v = new Bike();
        v.run();
    }
}
    

Console Output:

Bike is running safely

Polymorphism in Interfaces

Using Interfaces for Polymorphism

Interfaces in Java can be used to achieve polymorphism. A single interface can be implemented by multiple classes, and the methods can be overridden to provide specific functionality.


interface Drawable {
    void draw();
}

class Circle implements Drawable {
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

class Rectangle implements Drawable {
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

public class TestInterface {
    public static void main(String[] args) {
        Drawable d;
        d = new Circle();
        d.draw();
        d = new Rectangle();
        d.draw();
    }
}
    

Console Output:

Drawing a circle

Drawing a rectangle

Dynamic Method Dispatch

What is Dynamic Method Dispatch?

Dynamic method dispatch is a mechanism by which a call to an overridden method is resolved at runtime, rather than compile-time. This enables runtime polymorphism in Java.


class Parent {
    void show() {
        System.out.println("Parent's show()");
    }
}

class Child extends Parent {
    void show() {
        System.out.println("Child's show()");
    }
}

public class TestDynamicDispatch {
    public static void main(String[] args) {
        Parent p = new Child();
        p.show();
    }
}
    

Console Output:

Child's show()

Polymorphism with Abstract Classes

Abstract Classes and Polymorphism

Abstract classes allow you to define methods that must be created within any child classes built from the abstract class. They provide a base for subclasses to build upon and achieve polymorphism through method overriding.


abstract class Shape {
    abstract void draw();
}

class Triangle extends Shape {
    void draw() {
        System.out.println("Drawing a triangle");
    }
}

class Square extends Shape {
    void draw() {
        System.out.println("Drawing a square");
    }
}

public class TestAbstract {
    public static void main(String[] args) {
        Shape s;
        s = new Triangle();
        s.draw();
        s = new Square();
        s.draw();
    }
}
    

Console Output:

Drawing a triangle

Drawing a square

Polymorphism with Constructors

Constructor Polymorphism

While constructors themselves are not polymorphic, they play a crucial role in the instantiation of polymorphic objects. The type of the reference variable determines which overridden method is called.


class Base {
    Base() {
        System.out.println("Base constructor");
    }
}

class Derived extends Base {
    Derived() {
        System.out.println("Derived constructor");
    }
}

public class TestConstructor {
    public static void main(String[] args) {
        Base b = new Derived();
    }
}
    

Console Output:

Base constructor

Derived constructor

Polymorphism in Collections

Collections and Polymorphism

Java Collections Framework leverages polymorphism extensively. Collection interfaces provide a way to manipulate collections independent of the details of their representation.


import java.util.*;

public class TestCollections {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");

        for (String fruit : list) {
            System.out.println(fruit);
        }
    }
}
    

Console Output:

Apple

Banana

Polymorphism with Generics

Generics and Polymorphism

Generics in Java enable types (classes and interfaces) to be parameters when defining classes, interfaces, and methods. This adds a layer of abstraction and enhances polymorphism by ensuring type safety.


class Box {
    private T t;

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

public class TestGenerics {
    public static void main(String[] args) {
        Box integerBox = new Box<>();
        integerBox.set(10);

        Box stringBox = new Box<>();
        stringBox.set("Hello Generics");

        System.out.println(integerBox.get());
        System.out.println(stringBox.get());
    }
}
    

Console Output:

10

Hello Generics

Polymorphism with Anonymous Classes

Anonymous Classes and Polymorphism

Anonymous classes enable you to make your code concise. They are expressions that define a class and instantiate it in a single statement, often used for implementing interfaces or extending classes on the fly.


interface Message {
    void showMessage();
}

public class TestAnonymous {
    public static void main(String[] args) {
        Message m = new Message() {
            public void showMessage() {
                System.out.println("Hello from anonymous class");
            }
        };
        m.showMessage();
    }
}
    

Console Output:

Hello from anonymous class

Polymorphism with Lambda Expressions

Lambda Expressions and Polymorphism

Lambda expressions in Java provide a clear and concise way to represent a single method interface using an expression. They are a key feature in Java 8 for enabling functional programming and enhancing polymorphism.


interface Calculator {
    int operation(int a, int b);
}

public class TestLambda {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        Calculator multiply = (a, b) -> a * b;

        System.out.println("Addition: " + add.operation(5, 3));
        System.out.println("Multiplication: " + multiply.operation(5, 3));
    }
}
    

Console Output:

Addition: 8

Multiplication: 15

logo of wikigalaxy

Newsletter

Subscribe to our newsletter for weekly updates and promotions.

Privacy Policy

 • 

Terms of Service

Copyright © WikiGalaxy 2025