Skip to content

Virtual Methods

Isaac Shelton edited this page Sep 8, 2023 · 3 revisions

Virtual Methods

Virtual methods are methods which are dispatched at runtime. They are defined on classes and called like regular methods. Unlike regular methods however, the subject value must be constructed.

This is why all classes are required to define a constructor.

Virtual Methods Example

import basics

class Shape () {
    constructor {}

    virtual func getArea() float = 0.0
}

class Rectangle extends Shape (w, h float) {
    constructor(w, h float){
        this.w = w
        this.h = h
    }

    override func getArea() float = this.w * this.h
}

func main {
    shape *Shape = new Rectangle(5.0f, 10.0f)
    defer delete shape
    print(shape.getArea())
}

Virtual methods can even be used alongside features such as compile-time polymorphism, default values, and more.

Syntax

Top-most virtual methods are prefixed using the virtual keyword.

Virtual methods which override those of parent classes, must use the override keyword instead.

If no suitable definition exists from ancestor classes to override, a compile-time error will occur.

Internal Details

Virtual methods are not directly callable. Instead, a stub method will be created to allow for calling a virtual method on any value of the class or sub-class.

For example, the virtual method on this class:

struct Shape () {
    constructor {}
    
    virtual func getArea() float {
        return 0.0f
    }
}

would only be callable using the generated stub method, which would look like this:

func getArea(this *$This extends Shape) float {
    // virtual dispatch takes place here
}

Only top-level virtual methods generate stub methods. These stub methods are responsible for all dynamic dispatch for a single virtual method signature. For example, even if we created a Rectangle class which extended Shape and overrided its getArea method, the new method would only be callable through this stub method. This is not important from a programmer's perspective, but it is helpful to know how it works internally.

Clone this wiki locally