Реализация интерфейса, который имеет метод, возвращающий интерфейс, но получающий не реализованную ошибку - PullRequest
0 голосов
/ 04 ноября 2018

Я делаю кое-что для класса ИИ, но у меня, похоже, есть проблемы со структурой проекта. Я знаю, что это легче сделать в Python, но я уже сделал это, и я делаю это на Java, потому что у меня есть время, чтобы убить.

Мои классы настроены так:

  1. У меня есть 3 интерфейса: ProblemInterface, ActionInterface, StateInterface.
  2. У меня есть класс Search, который вызывает методы, определенные в ProblemInterface, и, следовательно, сохраняет ArrayList из ProblemInterface s.
  3. У меня есть класс ProblemQ1, который (пытается) реализовать ProblemInterface. Другие классы ActionQ1 и StateQ1 реализуют свои соответствующие интерфейсы.
    • class ProblemQ1 implements ProblemInterface
    • class ActionQ1 implements ActionInterface
    • class StateQ1 implements StateInterface
  4. ProblemInterface определяет метод с именем actions(), который принимает аргумент StateInterface и возвращает ArrayList<ActionInterface>. Итак, что-то вроде:
    • ArrayList<ActionInterface> actions(StateInterface state);
  5. Следовательно, мой ProblemQ1 класс пытается определить actions(), приняв аргумент StateQ1 и вернув ArrayList из ActionQ1.
    • public ArrayList<ActionQ1> actions(StateQ1 state)
  6. Класс ProblemQ1 не может быть абстрактным, потому что я должен его создавать для каждой проблемы, которую хотел бы решить.
  7. Позже я должен создать другие классы ProblemQN, StateQN и ActionQN, которые реализуют их соответствующие интерфейсы.

Однако, я получаю ошибку компилятора, которая говорит мне, что мой класс ProblemQ1 должен быть абстрактным или реализовывать метод ProblemInterface. Из того, что я вижу, он следует правилам интерфейса, и я не могу понять, почему он не будет воспринимать определение actions() в ProblemQ1 как определение интерфейса.

1 Ответ

0 голосов
/ 04 ноября 2018

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

Нет, вы изменили тип параметра метода в ProblemQ1:

public ArrayList<ActionQ1> actions(StateQ1 state)

В то время как интерфейс определяет метод как:

ArrayList<ActionInterface> actions(StateInterface state);

Это означает, что вы перегружаете, а не переопределяете метод. Аннотируйте метод с помощью @Override, и вы увидите, что компилятор не считает его переопределением.
Также обратите внимание, что переопределенный тип возврата также несовместим.
ArrayList<ActionQ1> не является подклассом ArrayList<ActionInterface>.
Но ArrayList<ActionQ1> является подклассом ArrayList<? extends ActionInterface>.

Для решения вашей проблемы вы можете ввести дженерики в интерфейс:

public interface ProblemInterface<T extends StateInterface, U extends ActionInterface>{   
    ArrayList<U> actions(T state);
}

А реализация может быть такой:

public class ProblemQ1 implements ProblemInterface<StateQ1, ActionQ1>{

    public ArrayList<ActionQ1> actions(StateQ1 state){
      // ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...