简体   繁体   English

具有泛型的Java复合设计模式

[英]java composite design pattern with generics

I have two interfaces which are generic, IComparable<T> , with method public boolean gt(T t) and ICombinable<T> , with method public T combine(T t) , and a third interface IPreferenceValue<T> which extends both these interfaces, ie, IPreferenceValue<T> extends IComparable<T>, ICombinable<T> , so that a preference value of type T can be compared and combined with other T 's. 我有两个通用的接口, IComparable<T> ,使用方法public boolean gt(T t)ICombinable<T> ,使用方法public T combine(T t) ICombinable<T> public T combine(T t) ,第三个接口IPreferenceValue<T>扩展了这两个接口接口(即IPreferenceValue<T> extends IComparable<T>, ICombinable<T> ,以便可以比较类型T的优先级值并将其与其他T组合。 I have two concrete implementations of IPreferenceValue, one being a single-valued implementation : IntegerValue implements IPreferenceValue<IntegerValue> and the other being a List of preference values: PreferenceVector<S extends IPreferenceValue<S>> implements IPreferenceValue<PreferenceVector<S>> . 我有两个IPreferenceValue的具体实现,一个是单值实现: IntegerValue implements IPreferenceValue<IntegerValue> ,另一个是首选项值列表: PreferenceVector<S extends IPreferenceValue<S>> implements IPreferenceValue<PreferenceVector<S>>

Elsewhere I have an algorithm that performs various things on IPreferenceValues and I want to treat the single valued and list valued Preference values the same way via the interface, like the Composite Design Pattern. 在其他地方,我有一种算法可以对IPreferenceValues执行各种操作,并且我想通过接口以相同的方式(如“复合设计模式”)来处理单值和列表值的Preference值。 I also want to have some sort of Factory that would create IPreferenceValues based on some parameter, ie, create a single-value object, or create a list-valued object. 我还想拥有一种工厂,该工厂将基于某些参数创建IPreferenceValues,即创建一个单值对象或创建一个列表值对象。 However when I am creating these PreferenceValues, I don't care about the type Parameter, I just want to create objects of type IPreferenceValue, the factory would return the concrete implementation - and just use the interface to interact with the objects. 但是,当我创建这些PreferenceValues时,我并不关心Parameter类型,我只想创建IPreferenceValue类型的对象,工厂将返回具体的实现-并仅使用接口与对象进行交互。

However I am having some difficulty getting this to work. 但是,我在使它起作用方面有些困难。 Firstly if I declare my values using the raw type IPreferenceValue, I am getting these warnings - " IPreferenceValue is a raw type. References to generic type IPreferenceValue<T> should be parameterized ". 首先,如果我使用原始类型IPreferenceValue声明值,则会收到以下警告-“ IPreferenceValue is a raw type. References to generic type IPreferenceValue<T> should be parameterized ”。 Are these warnings avoidable? 这些警告可以避免吗? Elsewhere, where I declare them as IPreferenceValue<?> , I get the following error: The method gt(capture#6-of ?) in the type IComparable<capture#6-of ?> is not applicable for the arguments (IPreferenceLevel<capture#7-of ?>) . 在其他地方,将它们声明为IPreferenceValue<?> ,出现以下错误: The method gt(capture#6-of ?) in the type IComparable<capture#6-of ?> is not applicable for the arguments (IPreferenceLevel<capture#7-of ?>) Any advice or pointers greatly appreciated... 任何建议或指针都非常感谢...

EDIT: Here is where I get the second error ( The method gt(capture#12-of ?) in the type IComparable<capture#12-of ?> is not applicable for the arguments (IPreferenceLevel<capture#13-of ?>) ) 编辑:在这里我得到第二个错误( The method gt(capture#12-of ?) in the type IComparable<capture#12-of ?> is not applicable for the arguments (IPreferenceLevel<capture#13-of ?>)

private IPreferenceLevel<?> calculateMinValue()
{
    IPreferenceLevel<?> min = null;
    for (IPreferenceLevel<?> value : tupleToValueMap.values())
    {
        if ((min == null) || (min.gt(value).equals(Comparison.TRUE)))
        {
            min = value;
        }
    }
    return min;
}

However even when I put in a type for this method, ie, if i rewrite as follows - 但是,即使我为此方法输入了一种类型,即,如果我按如下方式重写-

private <X> IPreferenceLevel<X> calculateMinValue()
{
    IPreferenceLevel<X> min = null; ...

This still doesn't compile - The method gt(X) in the type IComparable<X> is not applicable for the arguments (IPreferenceLevel<capture#10-of ?>) 这仍然无法编译- The method gt(X) in the type IComparable<X> is not applicable for the arguments (IPreferenceLevel<capture#10-of ?>)

You haven't given enough context about the specific error cases for me to be able to definitively point out what the issue is. 您没有为特定的错误情况提供足够的背景信息,以使我能够明确指出问题所在。 So I'll have to give more general pointers. 因此,我将不得不给出更多一般性的指示。

Firstly, the raw type warning is correct. 首先,原始类型警告是正确的。 Raw types arguably only exist for backwards compatibility, and you should never use them in new code. 原始类型可以说仅是为了向后兼容而存在,并且您永远不应在新代码中使用它们。 An IPreferenceValue always has a generic type - if you have no idea what it is and don't care, return it as an IPreferenceValue<?> as you've already done. IPreferenceValue始终具有泛型类型-如果您不知道它是什么并且不在乎,请像已经完成的一样将其作为IPreferenceValue<?>返回。 This is fine, and essentially communicates that you don't know/care about the parameter. 很好,基本上可以传达您不知道/不在乎该参数的信息。 (Of course, if you know what it might be, then by all means provide a more specific parameter.) (当然,如果您知道它可能是什么,那么一定要提供一个更具体的参数。)

The second error seems legitimate - you need to pass in a T but you're trying to pass in an IPreferenceValue<T> . 第二个错误似乎是合法的-您需要传递T但是您试图传递IPreferenceValue<T>

But also, once you fix this you'll still have a problem. 但是,一旦解决此问题,仍然会有问题。 The underlying error occurs in a completely different way and is not too unusual with generics. 潜在的错误以完全不同的方式发生,对于泛型来说并不太常见。 You've got a reference to an IPreferenceValue<?> and you're trying to call its gt method, which is defined to take a T . 您有对IPreferenceValue<?>的引用,并尝试调用其gt方法,该方法定义为采用T But you've just said that you have absolutely no idea what T is for that object (which is why you used the wildcard) - if you don't know what the generic parameter is, how can you pass in anything to it and know it's of the correct type? 但是您刚刚说过,您完全不知道该对象的T是什么(这就是为什么使用通配符的原因)-如果您不知道泛型参数是什么,那么如何将任何信息传递给它并知道它是正确的类型?

Specifically, you're trying to compare the contents of the tupleToValueMap with each other. 具体来说,您正在尝试将tupleToValueMap的内容相互比较。 In order to do that legally, their generic type parameters would have to be the same - how would you compare a IPreferenceLevel<IntegerValue> with a IPreferenceLevel<PreferenceVector<S>> ? 为了合法地执行此操作,它们的通用类型参数必须相同-如何将IPreferenceLevel<IntegerValue>IPreferenceLevel<PreferenceVector<S>>

So you should declare the type of the tupleToValueMap more specifically, giving it a concrete generic parameter for the preference levels rather than ? 因此,您应该更具体地声明tupleToValueMap的类型,为优先级提供一个具体的通用参数,而不是? . If it turns out that you can't do this because you're putting multiple types of preference level in there - then the compiler error is right, you can't compare them against each other safely. 如果事实证明您由于在其中放置了多种类型的首选项级别而无法执行此操作,那么编译器错误是正确的,您将无法安全地将它们相互比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM