Перегрузка метода разрешается во время компиляции.
Многократная отправка разрешается во время выполнения.
При использовании двойной диспетчеризации вызываемый метод зависит от фактического типа получателя и аргументов. Однако перегрузка метода позволяет только вызываемому методу зависеть от объявленного типа параметров. Зачем? Java связывает вызовы методов во время компиляции с их полной подписью (раннее связывание). Полная подпись включает все типы параметров, поэтому, когда фактический тип аргумента отличается во время выполнения (полиморфизм), перегрузка не работает, как вы могли ожидать!
void add(Foo o) { ... }
void add(Bar o) { ... }
void client() {
Foo o = new Bar();
add(o); // calls add(Foo) not add(Bar)!
}
с использованием нескольких отправок, однако
void add(Foo o) { o.dispatch(this); }
void add(Bar o) { o.dispatch(this); }
void client() {
Foo o = new Bar();
add(o); // calls #dispatch as defined in Bar!
}
В Scala все может немного отличаться, хотя общее различие должно быть таким, как представлено здесь на всех языках программирования.