Imperative Programming Part 3.
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
"AB". Through a receiver of static type A, only show(A) is visible. The argument's static type C is a subtype of A, so it can be passed to that method. Dynamic dispatch selects B.show(A) on the receiver object, exactly as in part (i). The argument's more specific type cannot expose overloads absent from the receiver's static type.Permitted; returns
"AB". A receiver of static type B exposes show(A) and show(B), but the argument's static type A is not a subtype of B. Only show(A) is applicable. Its effective implementation on the C receiver is B.show(A), which concatenates the superclass result "A" and "B".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.Permitted; returns
"BC". The receiver's static type is C, but the argument's static type is only B. Thus show(C) is inapplicable; among show(A) and show(B), the latter is more specific. Its implementation is C.show(B), whose superclass call returns "B" before "C" is appended. The argument happens to reference a C object, but method overloading uses its static type.Permitted; returns
"C". Both receiver and argument have static type C, so the most-specific applicable overload is show(C). That method is defined in C and returns its own one-letter result without calling super. The six results, in source order, are therefore AB, AB, AB, BC, BC, C.A mixin is reusable behavior supplied by a trait and composed into a class in object-oriented programming. Scala allows only one direct superclass, so mixins allow several independently reusable capabilities without multiple concrete-class inheritance. A trait can provide implemented methods and require abstract members from its host class.
trait Named {
def name: String
}
trait Greeting extends Named {
def greeting: String = "Welcome, " + name
}
class Account(val name: String)
class WelcomedAccount(name: String) extends Account(name) with Greeting
val example = new WelcomedAccount("reader")
assert(example.greeting == "Welcome, reader")Here the single superclass supplies
name, and the mixin supplies the derived greeting. The same behavior can be mixed into another unrelated host that satisfies Named. Mixin composition uses a defined linearization and requires incompatible concrete member conflicts to be resolved; it does not make arbitrary combinations of concrete superclasses legal.[ref]Class Composition with Mixins in the Scala documentation. A class has one superclass and can include several traits
Articles by others on the same topic
There are currently no matching articles.