In Swfit, we are able to use dynamicType to get the type of object at runtime (which means its actual type, instead of the type seen by the compiler). However, this does not help us to tell specified methods from others by its dynamic type at runtime. In other words, multimethods are not supported in Swift.

For example, we can overload some methods with same name, but different parameters:

class Pet {}
class Cat: Pet {}
class Dog: Pet {}

func printPet(pet: Pet) {
    print("Pet")
}

func printPet(cat: Cat) {
    print("Meow")
}

func printPet(dog: Dog) {
    print("Bark")
}

When calling them, the compiler will help us to find the correct version:

printPet(Cat()) // Meow
printPet(Dog()) // Bark
printPet(Pet()) // Pet

With instances of Cat and Dog, the most suitable version will be found, instead of calling a common super Pet version. Remember all of these happen at compile time. Consider the code below:

func printThem(pet: Pet, cat: Cat) {
    printPet(pet)
    printPet(cat)
}

printThem(Dog(), Cat())

// Output:
// Pet
// Meow

We pass a Dog() to printThem, but from the compiler's perspective, it is a Pet object. So when we call printPet method, the Pet version is chosen instead of the more specified Dog version. By default, Swift will not use multiple dispatch (or multimethods), but follows the compiling information.

If you want to get workaround of it, you can just check and convert the input type to what you want:

func printThem(pet: Pet, cat: Cat) {
    if let aCat = pet as? Cat {
        printPet(aCat)
    } else if let aDog = pet as? Dog {
        printPet(aDog)
    }
    printPet(cat)
}

// Output:
// Bark
// Meow