static and run time Polymorphism

Comprehensive study notes, diagrams, and exam preparation for static and run time Polymorphism.

Static and Run Time Polymorphism

Definition

Polymorphism is the ability of one interface or method name to represent multiple behaviors.

Static polymorphism

  • : The method to be executed is determined at compile time. It is commonly achieved through method overloading and operator overloading.

Run-time polymorphism

  • : The method to be executed is determined at run time. It is commonly achieved through method overriding using inheritance and dynamic method dispatch.

In short, static polymorphism depends on the type information known at compile time, while run-time polymorphism depends on the actual object created during execution.


Main Content

1. Static Polymorphism

Static polymorphism is also called compile-time polymorphism because the compiler decides which method or operation to use before the program runs. It is “static” because the binding between the method call and the method definition does not change during execution.

Method overloading

  • Method overloading means having multiple methods with the same name but different parameter lists in the same class.
  • The compiler selects the correct method based on the number, type, or order of arguments.
  • Example:
    class Calculator {
        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;
        }
    }
Here, the method name `add()` is reused, but the compiler chooses the correct version depending on the arguments.

Operator overloading

  • In some languages like C++, operators can be given additional meanings for user-defined types.
  • For example, the + operator can be used to add objects such as complex numbers or strings.
  • Example idea in C++:
    Complex c3 = c1 + c2;
The `+` operator is overloaded so that it can add complex number objects.
  • Note: Operator overloading is not supported in the same way in all languages; for example, Java does not allow general operator overloading.

Key features of static polymorphism:

  • Faster execution because method selection is done at compile time.
  • Easier to implement in many cases.
  • Commonly used when behavior differs based on input types or argument counts.
  • Does not require inheritance.

2. Run-Time Polymorphism

Run-time polymorphism is also called dynamic polymorphism because the method to be executed is determined while the program is running. It occurs when a base class reference points to a derived class object, and the overridden method of the derived class is called.

Method overriding

  • Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its parent class.
  • The method signature must generally remain the same, while the behavior changes.
  • Example:
    class Animal {
        void sound() {
            System.out.println("Animal makes a sound");
        }
    }

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

    class Main {
        public static void main(String[] args) {
            Animal a = new Dog();
            a.sound();   // Dog barks
        }
    }
Even though `a` is declared as `Animal`, the actual object is `Dog`, so the `Dog` version of `sound()` runs.

Dynamic method dispatch

  • This is the mechanism by which a call to an overridden method is resolved at run time.
  • The JVM or runtime environment checks the actual object type, not just the reference type.
  • It allows a single parent reference to refer to different child objects at different times.
  • Example:
    Animal a;

    a = new Dog();
    a.sound();   // Dog barks

    a = new Cat();
    a.sound();   // Cat meows

Key features of run-time polymorphism:

  • Requires inheritance or interface implementation.
  • Achieved using method overriding.
  • More flexible and extensible than static polymorphism.
  • Helps in designing systems that can work with many future object types.

ASCII diagram for run-time polymorphism:

        Animal
          |
   ----------------
   |              |
  Dog            Cat

Animal reference
      |
      v
   actual object at runtime

The reference type is Animal, but the actual behavior depends on whether the object is Dog or Cat.


3. Differences Between Static and Run-Time Polymorphism

Static and run-time polymorphism both support one of the core goals of object-oriented programming: using a common interface to achieve multiple behaviors. However, they differ in when and how the method selection happens.

Time of binding

  • Static polymorphism uses early binding or compile-time binding.
  • Run-time polymorphism uses late binding or dynamic binding.

How it is achieved

  • Static polymorphism is achieved through method overloading and sometimes operator overloading.
  • Run-time polymorphism is achieved through method overriding and inheritance.

Flexibility

  • Static polymorphism is less flexible because the method choice is fixed before execution.
  • Run-time polymorphism is more flexible because behavior can change depending on the actual object.

Example of comparison

  class Demo {
      void show(int a) {
          System.out.println("Integer version");
      }

      void show(String s) {
          System.out.println("String version");
      }
  }

This is static polymorphism because the compiler knows which show() method to use.

  class Parent {
      void display() {
          System.out.println("Parent");
      }
  }

  class Child extends Parent {
      @Override
      void display() {
          System.out.println("Child");
      }
  }

This is run-time polymorphism because the method called depends on the actual object.

ASCII diagram for comparison:

Compile time -----------------> Static polymorphism
         |
         +--> method selected by compiler

Run time ---------------------> Run-time polymorphism
         |
         +--> method selected by actual object

Working / Process

1. Static polymorphism is resolved by the compiler

  • When a program contains overloaded methods or overloaded operators, the compiler examines the method name, number of parameters, parameter types, and sometimes parameter order.
  • It then selects the most appropriate method before execution begins.
  • This means there is no ambiguity at run time because the decision is already made.

2. Run-time polymorphism is resolved during execution

  • When a base class reference points to a derived class object, the runtime system determines which overridden method to call.
  • The actual object type is checked at the moment of the method call.
  • This process is called dynamic method dispatch, and it makes programs more adaptable.

3. Object relationship and method call decide the behavior

  • In static polymorphism, the method signature decides the behavior.
  • In run-time polymorphism, the actual object decides the behavior.
  • Example flow: java Parent p = new Child(); p.display();

    • Reference type: Parent
    • Actual object type: Child
    • Result: Child’s version of display() is executed

ASCII diagram for process:

Program code
    |
    v
Method call made
    |
    +----------------------+
    | Static polymorphism  |
    | compiler checks args |
    | selects method early  |
    +----------------------+
    |
    +----------------------+
    | Run-time polymorphism |
    | runtime checks object |
    | selects method late   |
    +----------------------+

Advantages / Applications

Code reusability and cleaner design

  • Polymorphism allows the same method name or interface to represent many behaviors.
  • This reduces code duplication and makes programs easier to read and maintain.
  • For example, a single method name like draw() can work for circles, rectangles, and triangles.

Extensibility

  • Run-time polymorphism is especially useful when new classes may be added later.
  • Existing code can work with new subclasses without modification.
  • This follows the open-closed principle: open for extension, closed for modification.

Real-world modeling

  • Polymorphism is useful in applications where the same action has different meanings.
  • Examples include:
    • Payment processing (pay() in card, UPI, or cash systems)
    • Shapes (area() for circle, square, triangle)
    • Employees (calculateSalary() for permanent, contract, and hourly workers)
    • File handling (read() for text files, audio files, image files)

Improved maintainability

  • Static polymorphism makes code organized when multiple versions of a similar function are needed.
  • Run-time polymorphism simplifies large systems by reducing the need for many conditional statements like if-else or switch.

Performance vs flexibility

  • Static polymorphism is generally faster because the compiler resolves it early.
  • Run-time polymorphism is more flexible, though slightly slower due to dynamic dispatch.
  • Choosing the right type depends on whether performance or adaptability is more important.

Summary

  • Static polymorphism is compile-time method selection, usually through overloading.
  • Run-time polymorphism is execution-time method selection, usually through overriding.
  • Both help one interface support multiple behaviors in object-oriented programming.
  • Polymorphism improves reuse, readability, and flexibility.

  • Important terms to remember

  • Polymorphism
  • Static polymorphism
  • Run-time polymorphism
  • Method overloading
  • Method overriding
  • Compile-time binding
  • Dynamic binding