Работа с модификаторами доступа

Имеется некий абстрактный класс приведенный ниже.

abstract class Score{
    private double balance;

    protected String getBalance(String pin){
        if (check(pin))
            return Double.toString(balance);
        return "Введенный пин-код не корректен";
    }
    //баланс для внутренних операций
    protected Double getBalance(){
        return balance;
    }
}

Два метода нужны, потому что для ручных операций будет использоваться первый метод (с вводом пин-кода), а для автоматических операций второй (автоматические это например начисление кешбека).

Имеется наследник реализующий следующий функционал

public class RegularAccount extends Score{

    public void pay() {
        double price = super.getBalance() * 0.1;
        //TODO
    }
}

И все бы ничего, но если создать экземпляр класса RegularAccount, то можно вызвать метод getBalance() напрямую, чего хотелось бы запретить. Пробовал выносить метод в интерфейс, делать его абстрактным, просто игрался с модификаторами доступа, но все это не помогло или недопустимо.

По логике я предполагаю, что метод getBalance() в абстрактном классе должен быть private, но как тогда его вызвать из наследника, таким образом, чтобы максимально обезопасить себя?

Есть ли какое-то решение для данной проблемы.


Ответы (2 шт):

Автор решения: Roman Konoval

Метод с модификатором доступа protected доступен из main только потому, что класс, в котором объявлен main находится в том же пакете (package) что и Score.

Поместите Score в отдельный пакет и доступа извне пакета не будет, кроме как у наследников.

Другой, более правильный, способ (а точнее это то, что нужно сделать независимо от правильного разбиения на пакеты) - это не давать клиенту вообще ссылку на конкретную реализацию (RegularAccount в вашем случае). Создайте интерфейс с методами, которые должен использовать клиент, и отдавайте клиенту интерфейс. В интерфейсе метода getBalance быть не должно, если клиентам его использовать нельзя.

Такой интерфейс имеет смысл поместить ближе к Score, т.е. может быть в том же пакете.

→ Ссылка
Автор решения: Андрей Туманов

Как вариант: Перекрыть метод getBalance в RegularAccount с выдачей сообщения что доступ запрещен. используйте метод getBalance(String pin) При этом использование метода предка остается допустимым.

→ Ссылка