Вы упомянули в ответе на комментарий, что «вызывающему не обязательно иметь доступ ко всем внутренним действиям класса».
Для меня это говорит о том, что вы хотите использовать интерфейс.
Создайте интерфейс, который описывает класс, который будет содержать этот секретный алгоритм:
package com.stevej;
public interface Longer {
public int longer();
}
Реализуйте этот интерфейс, используя ваш секретный алгоритм:
package com.stevej;
public class LongerImpl implements Longer {
private int longer(int n){
return 0; // whatever
}
@Override
public int longer() {
return longer(5); // whatever
}
}
Теперь вызывающий объект создает объекты только с использованием определения интерфейса, гарантируя, что не существует открытых методов, к которым он может получить доступ случайно. Эта реализация подключена к этому объекту, определенному интерфейсом:
package com.stevej;
public class LongerProcessor {
Longer longerImpl = new LongerImpl();
public LongerProcessor() {
super();
}
public int longer() {
return longerImpl.longer();
}
}
Теперь вы можете переписывать реализацию Longer так часто, как вам нравится. Пока определение интерфейса никогда не изменяется, у вызывающей стороны (LongerProcessor) никогда не будет проблем. Черт, у вас может быть две или более разных реализаций (LongerImplRecursive, LongerImplBruteForce и т. Д.), Каждая из которых реализует Longer, и все они используются в разных местах одной и той же программы:
package com.stevej;
public class LongerProcessor {
Longer longerImpl;
public LongerProcessor(boolean useRecursive) {
super();
if (useRecursive){
longerImpl = new LongerImplRecursive();
}else{
longerImpl = new LongerImplBruteForce();
}
}
public int longer() {
return longerImpl.longer();
}
}
Насколько это круто? Поскольку вы пометили этот вопрос как «домашнее задание», мне интересно, должна ли проблема привлечь вас к размышлению о выделении контракта (интерфейса) и реализации (класса реализации).