引用类型中的多继承泛型 [英] Multiple inheritance generics in reference type

查看:550
本文介绍了引用类型中的多继承泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定:带有泛型类型T的类,它们都扩展并实现了一个接口

  class RescheduableRunnableIntent< T extends Intent& amp; amp; amp; amp; ; Timmed>实现Runnable {
IntentManager intentManager;
T意图;
}

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

  private HashSet <?扩展意向& Timmed>组; 


解决方案

我不喜欢使用类型通配符,因为它们是太严格了。举例来说,请检查以下代码示例:

 列表< ;?扩展Number> listExtendsNumber = new ArrayList<>(Arrays.asList(1,2,3)); 
Number num = new Integer(1);
listExtendsNumber.add(num); //编译错误 - 你不能添加东西
listExtendsNumber.add(1); //编译错误 - 你不能添加任何东西

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



在你需要弄清楚你是否想接受任何扩展 Intent Timmed 类型,或者只是一个特定类型?



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

1。围绕 Set



的包装您可以指定一个处理一种特定类型的包装:

  public class TimmedIntentSet< T extends Timmed&意图>实现Set< T> {


私人套餐< T> set = new HashSet<>();

//考虑定义默认以外的构造函数
$ b @Override
public int size(){
return set.size();


@Override
public boolean isEmpty(){
return set.isEmpty();
}
// ...更多委托方法
}

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

  public interface Timmed {} 
public interface Intent {}
公共接口TimmedIntent扩展了Timmed,Intent {}
public class TimmedIntentClass implements TimmedIntent {}
public class TimmedAndIntent1 implements Timmed,Intent {}
public class TimmedAndIntent2 implements Timmed,Intent {}

如果您对某些类型检查警告感到满意,那么您可以使用 TimmedIntentSet

  TimmedIntentSet tis = new TimmedIntentSet<>(); //警告
tis.add(new TimmedAndIntent1()); //警告
tis.add(new TimmedAndIntent2()); //警告
tis.add(new TimmedIntentClass()); //警告
tis.add(2); //编译错误

但是,如果您不想 @Suppress 您的警告,那么您将看到不止一些限制:

  TimmedIntentSet< TimmedIntentClass> tis = new TimmedIntentSet<>(); 
tis.add(new TimmedAndIntent1()); //编译错误
tis.add(new TimmedAndIntent2()); //编译错误
tis.add(new TimmedIntentClass()); // cool
tis.add(2); //编译错误



2。将 Set 添加到它所在的类中



您可以在刚才指定的类中添加一个Set以上。这接受了一个特定类型:

  class RescheduableRunnableIntent< T extends Intent& Timmed>实现Runnable {
IntentManager intentManager;
T意图;
Set< T> intentMap;

$ / code>

您可以定义一个新类型,它既是 Timmed Intent ,但有其他限制。使用与上面相同的类型,您不能只添加任何 Timmed Intent -s到您的集合中:

 设置< TimmedIntent> set = new HashSet<>(); 
set.add(new TimmedAndIntent1()); //编译错误
set.add(new TimmedAndIntent2()); //编译错误
set.add(new TimmedIntentClass()); //只有这是好的



包装:



这一切都归结为你想要做什么?几乎所有的东西都有可能,但是每一种选择都有折衷。

Given: A class with a generic Type T which both extends and implements an interface

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

How can I specify the same condition for an ArrayList or Hashmap? The following line produces a syntax error

private HashSet<? extends Intent & Timmed> set;

解决方案

I prefer not to use the type wildcards because they are too restrictive. Say for instance, check this code sample:

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

Sometimes you really want to be this restrictive. However, what I found is that people who use bound wildcard types, they usually want something else.

In your you need to figure out whether you want to accept any type that extends Intent and Timmed, or just one particular type?

As far as I can tell, you have the following options:

1. A Wrapper around Set

You can specify a wrapper that deals with one particular type:

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
}

This can be quite flexible. Say for instance, consider the following types:

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 {}

If you're happy with some type-check warnings, then you can do almost anything with this 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

However, if you don't want to @Suppress your warnings, then you'll see more than a handful of restrictions:

    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. Add that Set to the class where it's used

You can add a Set into the class you've just specified above. This accepts one particular type:

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

You can define a new type that's both Timmed and Intent, but that has other kind of restrictions. Using the same types as above, you can't just add any of the Timmed and Intent -s to your set:

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

Wrapping up:

It all boils down to what you want to do? Almost anything is possible, but each choice comes with trade-offs.

这篇关于引用类型中的多继承泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆