Рекурсия, StackOverflowError
Подскажите, почему строка return getMoney().getAmount(); метода getAmount класса A возвращает программу в метод getMoney() класса B?
Что вообще означает getMoney().getAmount()?
Как getMoney() может вызывать другой какой-то метод? Разве getMoney() это не метод?
public class Solution {
public static void main(String[] args) {
System.out.println(new B().getAmount());
}
public static abstract class A {
abstract A getMoney();
public Object getAmount() {
return getMoney().getAmount();
}
}
public static class B extends A {
private double amount = 123d;
public B getMoney() {
return this;
}
}
}
Ответы (2 шт):
Изначально вызывается метод getAmount у класса B
new B().getAmount()
т.к у него нет своего метода (метод, который физически был бы определён в этом классе) getAmount, но он наследник класса A, то по принципу наследования вызывается метод родителя (т.к. подификатор доступа public, а не private, значит метод доступен в наследниках). В нём вызывается getMoney(). Этот метод уже определён в классе B и он возвращает ссылку на экземпляр своего класса (this). У экземпляра класса есть методы есессно. И так как getMoney() вернул объект B, то дальше конструкция .getAmount() абсолютно легальна и вызывает метод опять у объекта с типом B. Который запускает всё по кругу опять
Что вообще означает
getMoney().getAmount()?
КакgetMoney()может вызывать другой какой-то метод? РазвеgetMoney()это не метод?
По своему определению абстрактный метод getMoney() возвращает ссылку на экземпляр класса A, и уже для этого экземпляра вызывается метод getMoney(). Проблема именно в реализации метода getAmount() в классе A, где вызовы зацикливаются.
Для разрыва зацикливания нужно переопределить (override) метод getAmount() в классе B следующим образом:
public static class B extends A {
private double amount = 123d;
@Override
public B getMoney() {
return this;
}
@Override
public Number getAmount() {
return this.amount;
}
}
Тогда результат вызова будет корректный:
123.0