如何使接口扩展其自己的通用类型

时间:2019-04-04 22:44:06

标签: java generics interface software-design generic-programming

我想创建一个带有通用参数的合同(接口),该合同强制实现的类也必须是通用参数中指定的类型。

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扩展{{ 1}}。用Java可以做到吗?

1 个答案:

答案 0 :(得分:0)

您可以将其设置为自引用泛型类型:

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进行无限制的转换,可以使用use getThis methods,但我认为这样做确实不值得。