Dynamic Method Dispatch in Object-Oriented Languages
How do we know which method is invoked here in the following:
var x : Object; println(x.toString())
The invoked method depends on the dynamic type of 'x'.
We can view the method to execute as a field of function type
Simple implementation: store function pointers in the object
- if a class has 100 methods, each object of this class would have 100 fields
All objects of same class have same code pointers for methods
- introduce a table for each dynamic type, Virtual method table (vtable)
- dynamic type of object give a pointer to corresponding vtable
How can we call methods in supertypes?
- for single inheritance, we arrange methods in sequence, from superclass to subclass
- superclasses ignore entries from subclass
Code Showing Dynamic Dispatch
class Dialog { var title : String = _ def show = { println("[" + title + "]") } def showTwice = { show show } } class FancyDialog extends Dialog { var howFancy = "!!!" override def show = { println(title + howFancy) } def star = { title = title + "*" } } object Test extends Application { var x = new Dialog x.title = "D" x.show var y = new FancyDialog y.title = "FAD" y.show y.star x = y x.showTwice }
What output does this give?
Sketch of Compiled Code for Dynamic Dispatch
// Dialog ---------------------------------- def makeDialogObject = { new Array( 0 -> DialogVtable // offset 0 is vtable 4 -> _ // offset 4 is pointer to 'title' string } def Dialog.show = { println("[" + this(4) + "]") } def Dialog.showTwice = { this(0). // get vtable (0) // invoke show pocedure (first declared) this(0). // once again (0) } val DialogVTable = new Array( 0 -> Dialog.show 1 -> Dialog.showTwice ) // FancyDialog ---------------------------- def makeFancyDialogObject = { new Array( 0 -> FancyDialogVTable // vtable 4 -> _ // 'title', same position as in makeDialogObject 8 -> "!!!" // 'howFancy' string } def FancyDialog.show = { println(this(4) + this(8) } def FancyDialog.star = { this(4) = this(4) + "*" } val FancyDialogVTable = new Array( 0 -> FancyDialog.show // overriding Dialog.show 4 -> Dialog.showTwice // remains same 8 -> FancyDialog.star // subclass method ) // main var x = makeDialogObject x(4) = "D" // title x(0).(0) // show var y = makeFancyDialogObject y(4) = "FAD" // title y(0).(0) // show y(0).(8) // star x = y x(0).(4) // showTwice