Вы совершенно правы - версия m
в A
более конкретна, и это действительно проблема.
Поскольку вы фактически вызываете m
для экземпляра b
(т. Е. b.m(a, a)
), компилятор сначала проверяет, существует ли метод, соответствующий сигнатуре в B
. Поскольку B
действительно имеет метод, который проходит проверку типа (т.е. m(a: A, o2: Any): B
), пока все хорошо. Но хотя компилятор также проверяет суперкласс A
, он находит более конкретную версию m
(т. Е. m(a1: A, a2: A): A
).
Проблема в том, что вы вызвали m
для экземпляра B
, но вы явно просите компилятор найти метод, который принимает два аргумента типа A
. Компилятор теперь не уверен, какую версию вы намеревались выполнить, отсюда и ошибка компиляции.
Лучшим сообщением компиляции может быть:
"Эй, я нашел версию m
дальше по иерархии в A
, которая лучше соответствует вашим требованиям, но я вижу, что вы явно вызываете m
для B
(не A
) поэтому я не знаю, какой из них выбрать сейчас - лучше пометьте это, в противном случае, если я просто выберу один, вы можете не получить результаты, которые вы получили во время выполнения. "