Перегрузка метода - ссылка на неоднозначна

1

Я пытаюсь улучшить сцепление с функцией перегрузки.

У меня есть эта тестовая программа (простите меня за мою C-вдохновленную Java).

public class Test {
    static void f(int x, double y)
    {
        System.out.printf("%d, %f",x,y);
    }

    static void f(double x, int y)
    {
        System.out.printf("%f, %d", x, y);
    }


    public static void main(String args[]) {

    f(1, 2);

    }
}

теперь, если я позвоню,

f(1, 2);

Существует ошибка компилятора, *reference to f is ambiguous*

Почему эта ошибка? Не будем ли мы называть f(int, int)? Но такой метод не объявлен. Я ожидал, что "нет подходящего метода для f", но у меня его нет, почему?

  • 2
    «Мне также интересно узнать, какие результаты C ++ и C #» Это то, что вы можете попробовать сами.
  • 2
    Проблема не в том, что подходящего метода нет, а в том, что их два, и ни один из них не лучше соответствует (согласно правилам Java) фактическим аргументам вызова, чем другой.
Теги:
method-overloading
function-overloading

3 ответа

12
Лучший ответ

int преобразуется в double на всех этих языках, поэтому, если бы один из них был доступен, было бы легко: преобразовать значение, которое нужно преобразовать в double, и вызвать метод.

Но в этом случае оба метода являются "действительными" в том смысле, что каждый из них будет прекрасен сам по себе, но ни один не "лучше", чем другой, поскольку в каждом случае одному аргументу требуется только идентификация int int, а другие потребности int для double преобразования. Таким образом, как в Java, так и в С# это неоднозначно и с ошибкой компиляции будет терпеть неудачу. Я бы предположил, что это тоже в C++, но я точно не знаю. Как в Java, так и в С#, если у вас также был метод static void f(int x, int y), который был бы однозначно лучшим, чем любой из двух других, для вызова этого метода.

В случае сомнений вы должны ознакомиться с соответствующими языковыми спецификациями. Для Java раздел JLS 15.12 является важной частью. В спецификации С# 5 это раздел 7.5.

  • 0
    Спасибо, и проверка из спецификации это хорошая идея, никогда не думал, что.
1

В f(1, 2); оба числа могут быть интерпретированы как int или double, поэтому они неоднозначны. Вы можете прояснить это, написав вот так:

f(1., 2);

или

f(1d, 2);

Однако не рекомендуется перегружать метод с несколькими сигнатурами, которые имеют одинаковое количество параметров. Рекомендуется избегать таких перегрузок, насколько это возможно.

Классический пример того, как все может пойти не так с перегрузкой с таким же количеством параметров, от Джошуа Блоха Эффективная Java:

public class CollectionClassifier {
   public static String classify(Set<?> s) {
       return "Set";
   }
   public static String classify(Collection<?> c) {
       return "Unknown Collection";
   }
   public static void main(String[] args) {
       Collection<?>[] collections = {
           new HashSet<String>(),
           new ArrayList<BigInteger>()
       };
       for (Collection<?> c : collections) {
           System.out.println(classify(c));
       }
   }
}

Это будет печатать Unknown Collection дважды, и ее легко упустить.

1

у вас есть эти функции, которые ужасно близки друг к другу или лучше чувствуют двусмысленность для компилятора, чтобы понять, поэтому компиляторы смущаются, чтобы увидеть эти

static void f(int x, double y)

static void f(double x, int y)

Чтобы избавиться от этой путаницы или двусмысленности для компилятора, просто добавьте следующие

 static void f(int x, int y)

Я думаю, что этот комментарий объясняет это лучше для вас

Проблема заключается не в отсутствии метода, который имеет два параметра int. Проблема в том, что есть два метода, которые одинаково хороши в соответствии с правилами Java для сопоставления методам методов. Устраните один из существующих методов f(), и ошибка исчезнет. - Тед Хопп

  • 0
    это то, что я не получаю. У нас нет f (int, int). Разве это не значит, что у нас вообще нет этого метода, и поэтому я ожидал, что «метод не найден».
  • 0
    когда его нет в вашем коде, просто у вас его нет. Вы должны определить это, чтобы иметь это
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню