【问题标题】:How to make an interface extends its own generic type如何让接口扩展它自己的泛型类型
【发布时间】:2019-04-04 22:44:05
【问题描述】:

我想创建一个带有泛型参数的协定(接口),它强制实现的类也必须是泛型参数中指定的类型。

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&lt;X&gt;时,该类也必须实现X,但是上面的尝试有语法,因为我不能使SelfDefaultAlternativeDetailSupport扩展T。这在 Java 中可行吗?

【问题讨论】:

  • 真的不清楚您要做什么,而且您的示例不完整。你想解决什么设计问题?
  • 感谢您的考虑。在我的示例中,我想创建一个 Customer 实体,该实体具有 primary 详细信息以及零个或多个替代详细信息。类 Customer 本身 IS A CustomerDetail 包含主要细节。默认方法resolveDetail() 被简化,只是为了表明它将根据某些业务逻辑返回主要详细信息或替代详细信息之一。
  • 在具体类 (Customer) 中,我可以毫无问题地让类实现细节 (CustomerDetail)。问题是,我想将这个结构推广到一个合同中,以确保我系统中的任何此类类都具有这种结构
  • 首先,不能扩展泛型类型,类型层次需要在编译时知道(或通过反射指定)。其次,我仍然不明白您要解决什么设计问题。您的应用程序对这些类的基本要求是什么?您尝试实现什么功能以及使用什么数据?

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


【解决方案1】:

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

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,但我认为这并不值得。

【讨论】:

    猜你喜欢
    • 2018-07-13
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 2018-04-09
    • 2020-07-19
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多