When a message with a parameter is sent to an object, the resultant behaviour is defined by the implementation of that method in the receiver. Sometimes the behaviour must also be determined by the type of the parameter.
In some languages that encourage the use of a switch/case construct, one solution would be for the method to switch on the type of the parameter and to execute different code as a result. However, in Smalltalk no switch statement is provided and nested ifTrue:ifFalse: messages are frowned upon. If a new class of parameter object was added, then the switch code would also have to be modified to cater for the new class (a maintenance issue).
In Smalltalk a better solution is to make use of the polymorphic nature of the language and to use a technique known as double dispatching. This involves adding a new method (we'll call this a secondary method) to the classes of all the potential parameter objects and then calling this from the original method with the receiver as a parameter. The selector of the secondary method should be constructed from the primary method selector followed by the class name of the original receiver.
The Integer class hierarchy uses double dispatch to implement some of the arithmetic functions, including #+ (plus).
#+ is defined by Integer as follows:
Integer>>+ aNumber "Answer a Number which is the sum of the receiver and aNumber" ^aNumber addToInteger: self
Inside this method, we know that aNumber is being added to the receiver (which is an Integer). To avoid writing code to switch on the type of the parameter aNumber, we can simply ask aNumber to perform the calculation for us.
There is a default implementation of #addToInteger in Number
ArithmeticValue>>addToInteger: anInteger "Private - Answer the result of adding the receiver to the known integer, anInteger, by coercing the less general of it and the receiver. Overridden by subclasses which can implement more efficiently."
^anInteger retry: #+ coercing: self
Each subclass of Integer which requires specialist addition processing implements its own #addToInteger. For example the Fraction class knows how to add an integer to itself:
addToInteger: anInteger "Private - Add the known integer, anInteger, to the receiver. There is no need to rationalise the result." ^Fraction numerator: anInteger * denominator + numerator denominator: denominator