Dynamic dispatch 2026-10-24
Selection of an instance method implementation using the receiver's runtime type. It operates on the method signature already determined by the language's call typing and overload rules. It does not imply dispatch on every argument's runtime type; in particular, method overloading in Scala normally uses static argument types.
To analyze an ordinary overloaded instance call, first enumerate members visible through the receiver's static type and choose the applicable signature using argument static types. Only then use the receiver's runtime type to select the effective override of that signature. This two-stage rule explains why changing a reference's declared type can change the selected overload even when every reference points to the same object. A
super call selects the inherited implementation according to the language's superclass or linearization rules instead of recursively redispatching to the overriding body.Method overloading gives one name several parameter signatures, such as
show(A) and show(B). The compiler chooses an applicable signature using the receiver's static type and the argument expressions' static types, preferring a uniquely more specific applicable alternative. An argument whose type is a subtype of the parameter type is acceptable; ambiguous or inapplicable alternatives cause a compile-time error. The runtime type of an argument does not start a second overload search.Method overriding replaces an inherited implementation of the same method signature. After overload selection, ordinary instance calls use dynamic dispatch on the receiver's runtime type to select the most-derived implementation of that signature. A concrete inherited method requires the
override keyword in Scala; a super call invokes the corresponding superclass implementation instead of redispatching to the overriding body. In a trait stack, super follows the class's linearization.[ref]Scala 2.13 expressions specification. Overloading resolution: applicable alternatives and most-specific selection
[ref]Scala 2.13 classes and objects specification. Member lookup, overriding and override modifier
Permitted; returns
"AB". The receiver's static type is A, which offers show(A). The argument also has static type A, so that signature is selected. All three variables refer to the same object of runtime type C; the most-derived implementation of show(A) is inherited from B. Its super.show(o) calls A.show(A), producing "A", and it appends "B". C overrides show(B), not this selected signature.Permitted; returns
"BC". Through static type B, both show(A) and show(B) accept an argument of type C; method overloading selects the more specific show(B). The receiver's runtime type is C, so dynamic dispatch invokes C.show(B). Its super.show(o) calls B.show(B), returning "B", and the override appends "C". The show(C) overload is not visible through receiver type B. Runtime type 2026-10-24
The concrete type of a value or allocated object during execution. For ordinary instance methods in object-oriented programming, dynamic dispatch uses the receiver's runtime type after a signature has been selected. The runtime type of an argument does not in general restart compile-time method overloading.
Static type 2026-10-24
The type assigned to a program expression during type checking. It controls which members and overloads are available at that expression. A reference with a broad static type can designate an object with a narrower runtime type; that does not expose additional overloads through the broad reference.