Переопределение метода интерфейса в Java - PullRequest
0 голосов
/ 28 сентября 2018

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

В пакете, который использует JavaFX, есть класс, конструктор которого

public class App extends Application{
...
protected App(Logic logic) {
    this(logic.configuration().welcomeScreen, logic.configuration().name, Optional.of(logic));
}
}

И интерфейс такой:

public interface Logic extends X, Y {

default Configuration configuration() {
    return new Configuration(1000, "Hello world", true);
}
default void initialize() {
    System.out.println("Starting the application.");
}
}

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

public final class Configuration {
public final int tick;
public final String name;
public final boolean welcomeScreen;

public Configuration(int tick, String name, boolean welcomeScreen) {
    this.tick = tick;
    this.name = name;
    this.welcomeScreen = welcomeScreen;
}
}

вывод приложения:

 (1000, "Hello world", true)

Теперь, когда я создаю свое собственное расширение приложения, переопределение не проходит:

public class Test extends App implements Logic{  
@Override
public Configuration configuration() {
    return new Configuration(25, "Test", true);
}

public static void main(String[] args) {

launch(args); //launches the App
}

}

вывод:

(1000, "Hello world", true)

Приложение по-прежнему вызывает метод интерфейса по умолчанию.В чем причина этого и как обойти метод по умолчанию в этом случае?

1 Ответ

0 голосов
/ 28 сентября 2018

Подкласс должен объявить конструктор, который явно вызывает следующий родительский конструктор:

protected App(Logic logic) {
    this(logic.configuration().welcomeScreen, logic.configuration().name, Optional.of(logic));
}

В противном случае он не будет компилироваться в соответствии с опубликованным кодом ... И если он компилируется, это означает, что родительский класс имеетконструктор без аргументов.Это будет вызвано неявно (в скомпилированном классе), и это не то, что вы хотите вызвать, чтобы использовать переопределенный метод configuration().

Приложение и логика не должны быть связаны в Test.
Так что вы можете ввести класс для определения подкласса Logic:

public TestLogic implements Logic{         
  @Override
  public AppConfiguration configuration() {
    return new AppConfiguration(25, "Test", true);
  }
}

И добавить Testконструктор для передачи экземпляра Logic (здесь this):

public class Test extends App {     
  public Test() {
     super(new TestLogic());
  } 
}
...