ChangeListener как частный класс

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

Я уже заработал как лямбда-выражение:

character1.healthProperty().addListener( ((observable, oldValue, newValue) -> {
        System.out.println(observable);
        System.out.println(oldValue);
        System.out.println(newValue);
    }) );

Когда персонаж получает урон, он выводит:

IntegerProperty [значение: 333]

350

333

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

private class HealthPropertyListener implements ChangeListener<IntegerProperty> {

    @Override
    public void changed(ObservableValue<IntegerProperty> observable, Integer oldValue, Integer newValue) {
        // Do something
    }

Он не компилируется, потому что говорит мне, что я неправильно переопределяю метод.

Если я сделаю это по-другому, это сработает, но мне придется привести объект к целому числу, чтобы использовать их. Есть ли способ избежать этого уродливого актера?

private class HealthPropertyListener implements ChangeListener {

    @Override
    public void changed(ObservableValue observable, Object oldValue, Object newValue) {
        //Do something
    }

person Franch    schedule 29.06.2016    source источник


Ответы (3)


Обратите внимание, что SimpleIntegerProperty реализует ObservableValue<Number>. Поэтому вам нужен ChangeListener<Number>. Правильная подпись для метода changed для этого параметра типа будет

public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue)

См. javadoc для ChangeListener и javadoc для SimpleIntegerProperty

person fabian    schedule 29.06.2016

SimpleIntegerProperty реализует ObservableValue<Number>, поэтому правильная подпись должна быть:

public void changed (ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue)

Кроме того, с Java 8 вам действительно не нужно создавать для этого класс - вы можете использовать метод:

private void healthChanged (ObservableValue<? extends Number> obs, Number oldValue, Number newValue) {
    ...
}

...
// inside a method in the same class
character1.healthProperty().addListener(this::healthChanged);

См. также: Почему LongProperty реализует свойство, но не свойство?

person Itai    schedule 29.06.2016

Взгляните на изменен метод public interface ChangeListener<T>:

void changed(ObservableValue<? extends T> observable, T oldValue, T newValue)

Исходя из этого, правильная форма:

private class HealthPropertyListener implements ChangeListener<IntegerProperty> {

    @Override
    public void changed(ObservableValue<? extends IntegerProperty> observable, IntegerProperty oldValue,
            IntegerProperty newValue) {
    }
}

Ответ на этот вопрос может быть полезен:

Когда Дженерики Java требуют ‹? расширяет T› вместо ‹T›, и есть ли обратная сторона переключения?

person DVarga    schedule 29.06.2016