-
-
Notifications
You must be signed in to change notification settings - Fork 9
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.
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.
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.
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.