Структурная типизация в Java - соблюдение интерфейса без необходимости его импорта - PullRequest
0 голосов
/ 17 февраля 2019

Допустим, у меня есть простой интерфейс:

interface IGroupBy {
  String getGroupById();
}

Скажем, у меня есть список этого:

List<IGroupBy> v = List.of();

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

Есть ли способ как-то получить структурную типизацию в Java, используя дженерики?

List<T> v = List.of();

а потом рассказать компилятору Java о T?Что-то вроде:

<T hasInterface:IGroupBy>

Я полагаю, что один из способов получить часть пути - использование обобщений, подобных этому:

   interface IGroupBy<T> {
      T getGroupById();
   }

, оставшаяся часть - это имя метода.Но это все равно означает, что вы должны ссылаться на тот же самый точный интерфейс по имени / пакету.

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Я думаю, что в Java ближе всего к тому, чего вы хотите добиться, - лямбды и функциональные интерфейсы.Это хорошая статья для прочтения: https://www.baeldung.com/java-8-functional-interfaces

    List<Function<Integer, Object>> calculators = new ArrayList<>();

    calculators.add((number) -> externalCalculator.calculate(number));
    calculators.add((number) -> number * number);

    calculators.forEach(c -> c.apply(1));

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

Подводя итог, ява не лучший язык для таких вещей.

0 голосов
/ 17 февраля 2019

Я не уверен, что это то, о чем вы просите, но я полагаю, что вы говорите о java covariance .

По существу, допустим, что у вас есть следующий класс:

class  TestClass implements IGroupBy { 
    private String id; 
    TestClass(String id) {
        this.id = id;
    }   
    @Override
    public String getGroupById() {
        return id;
    }
}

А теперь, если у вас есть следующий список:

 List<TestClass> list = List.of(
                new TestClass("test1"),
                new TestClass("test2")
        );

Вы хотели бы написать что-то вроде:

List<IGroupBy> interfaceList = list;

Этоподдерживается в Java с помощью подстановочного знака и может быть сделано следующим образом:

List<? extends IGroupBy> interfaceList = list;
...