Как сделать интерфейс расширяет свой собственный универсальный тип - PullRequest
0 голосов
/ 05 апреля 2019

Я хотел бы создать контракт (интерфейс) с универсальным параметром, который предписывает, чтобы реализованный класс также был типом, указанным в универсальном параметре.

public interface SelfDefaultAlternativeDetailSupport<T extends AlternativeDetail> extends T { // syntax error (extends T)

    default T resolveDetail() {
        if (someConditions()) {
            return this;
        } else {
            return getAlternativeDetails().stream()
                    .filter(somePredicate)
                    .findFirst().orElse(null);
        }
    }

    List<T> getAlternativeDetails();
}

Пример использования

public interface CustomerDetail extends AlternativeDetail {
    String getName();
}

public class Customer implements SelfDefaultAlternativeDetailSupport<CustomerDetail>, CustomerDetail {
    @Override
    public String getName() {
        return "default name";
    }

    @Override
    public List<AlternativeDetails> getAlternativeDetails() {
        ...
    }
}

Другими словами, мне бы хотелось, чтобы когда класс реализовывал SomeInterface<X>, класс также должен реализовывать X, но приведенная выше попытка имеет синтаксис, поскольку я не могу сделать SelfDefaultAlternativeDetailSupport extends T.Возможно ли это в Java?

1 Ответ

0 голосов
/ 05 апреля 2019

Вы можете сделать его ссылочным универсальным типом:

public interface SelfDefaultAlternativeDetailSupport<T extends SelfDefaultAlternativeDetailSupport<T> & AlternativeDetail> {

    @SuppressWarnings("unchecked")
    default T resolveDetail() {
        if (someConditions()) {
            return (T) this;
        } else {
            return getAlternativeDetails().stream()
                    .filter(somePredicate)
                    .findFirst().orElse(null);
        }
    }

    List<T> getAlternativeDetails();
}

Тогда вы можете иметь:

public class Customer implements SelfDefaultAlternativeDetailSupport<Customer>, CustomerDetail {
    @Override
    public List<Customer> getAlternativeDetails() {
        ...
    }
}

Просто будьте осторожны, чтобы никогда не использовать другой класс в качестве параметра дляSelfDefaultAlternativeDetailSupport.Если вы хотите избежать неконтролируемого броска this, вы можете использовать getThis методы , но я не думаю, что это действительно того стоит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...