Java, доступность анонимного внутреннего частного интерфейса

Я реализовал шаблон стратегии внутри класса, чтобы выполнить выполнение в соответствии с входными данными. Работает нормально и называется по-простому.

public class MyObject {

private final Object input;
private final Strategy strategy;

public MyObject(final Object input, final Strategy strategy) {
    this.input = input;
    this.strategy = strategy;
}

private interface Strategy {
    public void execute(final Object input);
}

public static final class FirstStrategy implements Strategy {
    @Override
    public void execute(final Object input) {...}
}

public static final class SecondStrategy implements Strategy {
    @Override 
    public void execute(final Object input) {...}
}

new MyObject(null, new MyObject.FirstStrategy());

Как только я наберу new MyObject(null, new MyObjectполный помощник Eclipse IDE предлагает мне реализовать частный интерфейс.

Выбор этого пункта приводит к ошибочной структуре, предлагающей мне создать класс Strategy так как это не видно другим классам.

new MyObject(null, new MyObject.Strategy() {
    @Override
    public void execute(Object input) {}
});

Я знаю, как работают анонимные внутренние типы и почему это происходит. Этот легко решается изменением видимости интерфейса strategy для публики - но это против того, что я хочу. Я настаиваю на том, чтобы не позволить клиенту использовать любую другую реализацию, кроме той, которую я ему предоставляю FirstStrategy или же SecondStrategy, Есть ли способ избавиться от этого предложения автозаполнения для реализации частного интерфейса и предоставления только ограниченных реализаций, одновременно использующих анонимный внутренний тип?

2 ответа

Решение

Если вы хотите разрешить только определенные подклассы, предоставьте перегруженные конструкторы для этих конкретных подклассов:

public MyObject(final Object input, final FirstStrategy strategy) {
  this(input, (Strategy) strategy);
}

public MyObject(final Object input, final SecondStrategy strategy) {
  this(input, (Strategy) strategy);
}

private MyObject(final Object input, final Strategy strategy) {
  // ...
}

Частный интерфейс может быть реализован только внутри MyObject учебный класс. Если клиент попытается реализовать его в каком-либо другом классе, он не скомпилируется. И даже если клиент создает свой собственный Strategy учебный класс, MyObject конструктор не примет это.

Относительно этого предложения автозаполнения - это просто не правильно.

Другие вопросы по тегам