Как назначить метод в качестве атрибута, чтобы использовать его позже для любого совместимого объекта?

#java #generics #method-reference

Вопрос:

Я пытаюсь создать универсальное меню над произвольным типом T , реализующим Menuable интерфейс:

 public interface Procedure {
    void invoke();
}

public class Menu<T extends Menuable> implements Menuable {
    List<T> items; //The items of the menu
    List<String> itemsDisplay; //A list of String specifying how to display each of the above items
    Procedure procedure; //A method to be performed on the elements of items

    public Menu(List<T> items, List<String> itemsDisplay) {
        this.items = items;
        this.itemsDisplay = itemsDisplay;
    }

    //Returns a String display of the menu
    //Each item is numbered and displayed as specified by the list itemsDisplay
    public String menuDisplay() {

        String s = "";
        
        int i;
        for (i = 1; i <= this.itemsDisplay.size(); i  ) {
            s = s   i   "t"   this.itemsDisplay.get(i-1)   "n";
        }
  
    return s;
    }
    ...
}
 

Меню будет напечатано на терминале, и когда пользователь выберет пункт, я хотел бы, чтобы меню могло выполнять любой метод экземпляра для этого пункта. В принципе, вот что я хотел бы сделать:

 public Menu(List<T> items, List<String> itemsDisplay, Procedure procedure) {
    this.items = items;
    this.itemsDisplay = itemsDisplay;
    Here I would like to assign a method to this.procedure for later use,
    but without specifying on which object to use it yet.
}

public void waitForAction() throws IOException {
        
    //Display the menu to the user
    System.out.println(this.menuDisplay());
    
    BufferedReader inputs = new BufferedReader(new InputStreamReader(System.in));

    int choice = 0;
    //Read inputs until the user enters a valid choice
    while(!(1 <= choice amp;amp; choice <= this.items.size())) {

        try {
            choice = Integer.parseInt(inputs.readLine());
        } catch(NumberFormatException e) {
        }
    }

    //The item selected is at index (choice - 1) in the list this.items
    Here I would like to use my method on this.items.get(choice - 1).
}
 

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

Комментарии:

1. Почему вы хотите использовать методы, если у вас могут быть простые объекты? Чтобы получить доступ к методам и работать с ними, вам нужно будет включить механизм отражения, в то же время у вас может быть какой-то простой интерфейс, аналогичный java.lang. Выполнимая, java.util.функция. Функция, java.util.функция. Потребитель и т.д. В данном конкретном случае, я думаю, будет хорошо использовать простого потребителя.

2. Не публикуйте все эти несущественные вещи. Нам не нужно знать, как вы собираете строки меню или как вы считываете целое число System.in . Ваш вопрос об этом Procedure , поэтому соответствующие части будут касаться того, как вы инициализируете procedure переменную и как вы вызываете ее метод, но вы ничего об этом не показали. Также было бы интересно, как Menuable определяется, поскольку кажется, что существует перекрытие между этим интерфейсом и Procedure