Lecture 10 – Polymorphism: Compile-time and Run-time

Polymorphism: Compile-time and Run-time

Learn Polymorphism in Object-Oriented Programming, including compile-time and run-time types. Understand method overloading, method overriding, virtual functions in C++, and dynamic binding in Java with practical coding examples.

What is Polymorphism?

Polymorphism comes from two Greek words:
Poly = many, Morph = forms
It means “one name, many forms.”

In Object-Oriented Programming, polymorphism allows one function, method, or operator to behave differently based on context depending on the type of object or number of arguments.

Definition:

Polymorphism is the ability of the same function or method to behave differently for different types of objects or inputs.

Lecture 9 – Inheritance in Practice

Types of Polymorphism

TypeDescriptionExample
Compile-time (Static)Decision made at compile timeMethod Overloading
Run-time (Dynamic)Decision made at runtimeMethod Overriding

Part 1: Compile-time Polymorphism (Static Binding)

Method Overloading

Method overloading means having multiple methods with the same name but different parameters (type, number, or order).

Example (C++):
#include <iostream>
using namespace std;

class Math {
public:
    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;
    }
};

int main() {
    Math m;
    cout << m.add(3, 4) << endl;        // Calls int version
    cout << m.add(2.5, 4.1) << endl;    // Calls double version
    cout << m.add(1, 2, 3) << endl;     // Calls 3-parameter version
}

Explanation:

  • The compiler decides which version of add() to call based on arguments.
  • This is known as compile-time binding.

Example (Java):

class MathUtils {
    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;
    }
}

public class Main {
    public static void main(String[] args) {
        MathUtils m = new MathUtils();
        System.out.println(m.add(3, 4));
        System.out.println(m.add(2.5, 4.5));
        System.out.println(m.add(1, 2, 3));
    }
}

Overloading increases flexibility and code readability.

Part 2: Run-time Polymorphism (Dynamic Binding)

Method Overriding

Method overriding occurs when a subclass provides a new implementation for a method already defined in its superclass.
Which version is executed depends on the object type at runtime.

Example (C++ with Virtual Functions):
#include <iostream>
using namespace std;

class Animal {
public:
    virtual void sound() {
        cout << "Animal makes a sound." << endl;
    }
};

class Dog : public Animal {
public:
    void sound() override {
        cout << "Dog barks." << endl;
    }
};

int main() {
    Animal* a;
    Dog d;
    a = &d;
    a->sound(); // Calls Dog's version due to virtual function
}

Explanation:

  • virtual tells the compiler to look for the method at runtime, not compile time.
  • Without virtual, the base version would be called even when pointing to a Dog.

Example (Java – Dynamic Binding):

class Animal {
    void sound() {
        System.out.println("Animal makes a sound.");
    }
}

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

public class Main {
    public static void main(String[] args) {
        Animal a = new Dog();  // Reference of parent, object of child
        a.sound();  // Calls Dog’s version (runtime decision)
    }
}

In Java, all non-static methods are virtual by default.
So the method call depends on the actual object created, not the reference type.

Operator Overloading (C++ Only)

C++ also supports operator overloading, allowing built-in operators to behave differently for objects.

Example:
#include <iostream>
using namespace std;

class Complex {
public:
    int real, imag;

    Complex(int r, int i) : real(r), imag(i) {}

    Complex operator + (Complex c) {
        return Complex(real + c.real, imag + c.imag);
    }

    void display() {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(2, 3), c2(4, 5);
    Complex c3 = c1 + c2;  // Uses overloaded +
    c3.display();
}

Advantages of Polymorphism

AdvantageDescription
Code ReusabilityUse the same function name for different tasks.
FlexibilityWorks with different object types dynamically.
ExtensibilityAdd new behaviors without changing existing code.
MaintainabilitySimplifies large applications by promoting clean hierarchies.

Summary of Lecture 10

ConceptTypeExample
Method OverloadingCompile-timeadd(int, int) & add(double, double)
Method OverridingRun-timesound() in Animal and Dog
Virtual FunctionEnables runtime decision (C++)virtual void sound()
Dynamic BindingJava runtime decisionAnimal a = new Dog()

Positive Thought for Students

“Polymorphism is the art of adaptability the same name, new power. In coding and life, flexibility makes you unstoppable.”

Leave a Reply

Your email address will not be published. Required fields are marked *