引用类型中的多继承泛型

时间:2017-12-17 16:18:29

标签: java generics

给定:具有通用类型T的类,它扩展并实现接口

class RescheduableRunnableIntent<T extends Intent & Timmed> implements Runnable{
    IntentManager intentManager;
    T intent;
}

如何为ArrayList或Hashmap指定相同的条件?以下行产生语法错误

private HashSet<? extends Intent & Timmed> set;

1 个答案:

答案 0 :(得分:0)

我不喜欢使用类型通配符,因为它们限制性太强。比如说,请检查此代码示例:

List<? extends Number> listExtendsNumber = new ArrayList<>(Arrays.asList(1, 2, 3));
Number num = new Integer(1);
listExtendsNumber.add(num); // compile error - you can't add stuff
listExtendsNumber.add(1);   // compile error - you can't add stuff

有时候你真的想成为这种限制性的。但是,我发现使用绑定通配符类型的人通常需要其他东西。

在您需要确定是否要接受扩展IntentTimmed任何类型,或只是一种特定类型?

据我所知,您有以下选择:

1。围绕Set

的包装器

您可以指定处理特定类型的包装器:

public class TimmedIntentSet<T extends Timmed & Intent> implements Set<T> {


    private Set<T> set = new HashSet<>();

    // consider defining constructors other than the default

    @Override
    public int size() {
        return set.size();
    }

    @Override
    public boolean isEmpty() {
        return set.isEmpty();
    }
    // ... more delegator methods
}

这可以非常灵活。比如说,请考虑以下类型:

public interface Timmed {}
public interface Intent {}
public interface TimmedIntent extends Timmed, Intent {}
public class TimmedIntentClass implements TimmedIntent {}
public class TimmedAndIntent1 implements Timmed, Intent {}
public class TimmedAndIntent2 implements Timmed, Intent {}

如果您对某些类型检查警告感到满意,那么您几乎可以使用TimmedIntentSet执行任何操作:

    TimmedIntentSet tis = new TimmedIntentSet<>(); // warning
    tis.add(new TimmedAndIntent1());  // warning
    tis.add(new TimmedAndIntent2());  // warning
    tis.add(new TimmedIntentClass()); // warning
    tis.add(2);                       // compile error

但是,如果您不想@Suppress发出警告,那么您会看到以下几项限制:

    TimmedIntentSet<TimmedIntentClass> tis = new TimmedIntentSet<>();
    tis.add(new TimmedAndIntent1());  // compile error
    tis.add(new TimmedAndIntent2());  // compile error
    tis.add(new TimmedIntentClass()); // cool
    tis.add(2);                       // compile error

2。将Set添加到已使用

的班级

您可以在上面指定的班级中添加一个Set。这接受一种特定类型:

class RescheduableRunnableIntent<T extends Intent & Timmed> implements Runnable{
    IntentManager intentManager;
    T intent;
    Set<T> intentMap;
}

您可以定义同时包含TimmedIntent的新类型,但这有其他类型的限制。使用与上述相同的类型,您只需添加TimmedIntent -s中的任何一个:

Set<TimmedIntent> set = new HashSet<>();
set.add(new TimmedAndIntent1());  // compile error
set.add(new TimmedAndIntent2());  // compile error
set.add(new TimmedIntentClass()); // only this is fine

结束:

这一切归结为你想做什么?几乎任何事情都是可能的,但每种选择都需要权衡利弊。