Polymorphism: virtual and override

The same call, s.Area(), runs different code depending on what kind of object s actually is.

Time O(1) per callSpace O(1)Code C++, Python and C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

The variable s has type Shape, but the object it points at is a Circle or a Square. For a virtual or abstract method, the runtime looks at the real object and runs that class's version.

Code

class Shape {
public:
    virtual double area() const = 0;
    virtual ~Shape() = default;
};
class Circle : public Shape {
public:
    double r = 1;
    double area() const override { return M_PI * r * r; }
};
class Square : public Shape {
public:
    double side = 2;
    double area() const override { return side * side; }
};

int main() {
    vector<unique_ptr<Shape>> shapes;
    shapes.push_back(make_unique<Circle>()); shapes.push_back(make_unique<Square>()); shapes.push_back(make_unique<Circle>());
    for (const auto& s : shapes)
        cout << s->area() << "\n";   // the object decides which area() runs
}
from abc import ABC, abstractmethod
import math

class Shape(ABC):
    @abstractmethod
    def area(self) -> float: ...

class Circle(Shape):
    r = 1
    def area(self) -> float: return math.pi * self.r * self.r

class Square(Shape):
    side = 2
    def area(self) -> float: return self.side * self.side

shapes = [Circle(), Square(), Circle()]
for s in shapes:
    print(s.area())  # the object decides which area runs
abstract class Shape {
    public abstract double Area();
}
class Circle : Shape {
    public double R = 1;
    public override double Area() => Math.PI * R * R;
}
class Square : Shape {
    public double Side = 2;
    public override double Area() => Side * Side;
}

var shapes = new List<Shape> { new Circle(), new Square(), new Circle() };
foreach (Shape s in shapes)
    Console.WriteLine(s.Area());   // the object decides which Area runs

Tips

In the .NET library

A method must be marked virtual or abstract in the base class and override in the derived class. Without those keywords C# binds the call at compile time.