Перевантажений різним типом повернення на Java?


104

Чому неможливо перевантажити функцію лише змінивши тип повернення? Чи зміниться це в майбутній версії Java?

До речі, лише для довідки, чи можливо це на C ++?



КНУ, інша відповідь відрізняється тим, що вона задає питання загалом, немовними специфічними термінами. Також цікаво те, що прийнята відповідь на інше питання йде далі, уточнюючи, що Java JVM дозволяє це робити з маніпуляціями з внутрішніми.
J Woodchuck

Відповіді:


157

Ви не можете робити це на Java, а також не в C ++. Обґрунтування полягає в тому, що одне повернене значення недостатньо, щоб компілятор розібрався, яку функцію викликати:

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

3
Я завжди думав, що якби ми зробили щось на кшталт int i = foo () або float f = foo (), він би знав, який з них, але якщо заява - це лише та функція, яку не знав би компілятор. Я знаю це. Дякую.
nunos

7
@nunos, навіть якщо це float f = foo (), компілятор не зможе розібратися в цьому, оскільки обидва int були б дійсними вхідними для float. Порівняйте поплавок f = 7; (це 7 float або int?)
NomeN

5
@NomeN Але ваше твердження говорить про те, що func (int i) і func (float i) не відрізнятимуться для компілятора - і всі ми знаємо, що це неправда. Справжню причину дає Одід (див. Наступну відповідь) - мова йде про підпис методу. І, btw. 7, безумовно, ціле число, тоді як 7,0 або 7f плаває ;-)
Ta Sas,

7
7,0 ні float, це double.
fredoverflow

3
Те, що foo();без типу повернення було б неоднозначним, не обов'язково є причиною заборонити це як перевантаження. Є аргументи, які можуть викликати неоднозначність (наприклад foo(null);), але це не робить перевантаження за своєю суттю недійсною.
shmosel

48

Причина полягає в тому, що перевантаження в Java дозволяється лише для методів з різними підписами .

Тип повернення не є частиною підпису методу, тому не може використовуватися для розрізнення перевантажень.

Див. Розділ Визначення методів із навчальних посібників Java.


4
Але чому тип повернення не є частиною підпису,
а

51
ой "просто тому"! Я бачу.
andho

3
Тип повернення IS - частина підпису методу. Досить поглянути на розбирання класів.
konmik

2
Це насправді не @konmik - не за правилами перевантаження методом. Спробуй це. Те саме ім'я методу, однакові типи параметрів у тому самому порядку, різні типи повернення. Не збирається.
Одід

3
Так, тому що тип повернення не є частиною підпису . Підпис - це назва методу + типи та порядок його параметра. Прочитайте посилання, яке я надав у своїй відповіді: "Підпис методу, оголошеного вище: calculateAnswer(double, int, double, double)". Дивіться, що тип повернення не включений, @konmik.
Одід

22

Перед Java 5.0, коли ви перекриєте метод, обидва параметри та тип повернення повинні точно відповідати. У Java 5.0 він вводить новий об'єкт, який називається коваріантним типом повернення. Ви можете замінити метод з однаковою підписом, але повертає підклас повернутого об'єкта. Іншими словами, метод підкласу може повернути об’єкт, тип якого є підкласом типу, повернутий методом з однаковою підписом у надкласі.


3
Я був збентежений, коли вперше побачив це. Дякую за пояснення, чому це можливо!
Ділан Ноулз

2
перевантаження і переосмислення різні. Перевантаження не обов'язково передбачає успадкування
Сенселю

3
Ця відповідь може здатися помилковою для новачків на Java, оскільки вона взагалі не має відношення до перевантаження , вона переважає - зовсім інша річ.
azizbekian

4

Overloaded методи в Java можуть мати різні типи повернення, враховуючи, що аргумент також різний.

Перевірте зразок коду.

public class B {

    public String greet() {
        return "Hello";
    }

    //This will work
    public StringBuilder greet(String name) {
        return new StringBuilder("Hello " + name);
    }

    //This will not work
    //Error: Duplicate method greet() in type B
    public StringBuilder greet() {
        return new StringBuilder("Hello Tarzan");
    }

}

в основному тип повернення не враховується, лише аргументи, сумні, але правдиві
Олександр Міллз

1

Компілятор не враховує тип повернення при диференціації методів, тому ви не можете оголосити два методи з однаковою підписом, навіть якщо вони мають інший тип повернення.


1

Тип повернення не має значення при перевантаженні методу. Нам просто потрібно переконатися у відсутності двозначності!

Єдиний спосіб, яким Java може знати, який метод викликати, - це диференціювати типи списку аргументів. Якби компілятор дозволив два методи з тим самим іменем та тими ж типом аргументів, не було б способу визначити, який із них слід викликати.


0

Компілятор не враховує тип повернення при диференціації методів, тому ви не можете оголосити два методи з однаковою підписом, навіть якщо вони мають інший тип повернення.

Якщо вам відомо про виконання функції, то ви будете знати, що коли ми викликаємо функцію, виконується частина визначення, і, нарешті, нам потрібен оператор повернення, отже, ми можемо сказати, що повернення відбувається після всього визначення функції, ось чому, якщо є дві або більше функцій з тим самим іменем, з тим самим типом і ні. аргументів, то під час виклику того, як компілятор буде знати про те, кого потрібно викликати, оскільки назва функції та параметри однакові. Під час виклику, по-перше, вся увага буде зосереджена на аргументах та імені функції, а після завершення визначення функції нарешті ми матимемо справу із поверненням.

Помилка часу компіляції краще, ніж помилка запуску часу. Отже, компілятор java робить помилку часу компілятора, якщо ви оголошуєте той самий метод, що має однакові параметри.


Чим це відрізняється від прийнятої відповіді? (Також причина, що це помилка часу компіляції, полягає в тому, що компілятор не може розібратися, який метод викликати, тому як слід генерувати належний виконуваний код)
UnholySheep

-2

не дуже можливо, таким чином ви можете перевантажуватися лише відсутністю аргументів або типом даних аргументів

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.