我可以有一个类字段,类是必须扩展另一个类和接口的类<! - ? - >吗?

时间:2014-03-08 23:46:41

标签: java generics

对不起,我似乎无法用更好的句子来问这个问题。我会试着澄清一下:

我的类(当前为enum,但将其移植到class并不是问题,如果它解决了这个问题)有一个Class字段,表示它将在运行时动态实例化的类型。

此类型必须扩展Fragment类(Android)并实施MyInterface

<F extends Fragment & MyInterface>

如何在代码中定义它?

目前有效的不完整的解决方案,无论是否实现MyInterface,它都会接受任何片段:

public enum Something {
  Value1 (OneFragmentInterfaceImplementor.class),
  Value2 (AnotherFragmentInterfaceImplementor.class);

  public final Class<? extends Fragment> fragment;

  private Something (final Class<? extends Fragment> fragmentClass) {
    fragment = fragmentClass;
  }
}

我真正想要的是,这个类不仅扩展了Fragment,还实现了MyInterface

我想要下面的正确形式:

public <F extends Fragment & MyInterface> enum Something {
  Value1 (OneFragmentInterfaceImplementor.class),
  Value2 (AnotherFragmentInterfaceImplementor.class);

  public final Class<F> fragment;

  private Something (final Class<F> fragmentClass) {
    fragment = fragmentClass;
  }
}

我在这里要求不可能吗?

更新 一个很好的建议是创建一个实现接口的抽象Fragment。不幸的是,这在我的特定用例中不起作用,因为其中一些片段扩展了其他已经实现的片段。

2 个答案:

答案 0 :(得分:5)

要在enum中使用,它不能使用泛型类型参数,请创建一个扩展Fragment并实现MyInterface的抽象类。让您的实现扩展此类。并将其与Class一起使用。

private final Class<AbstractClassThatExtendsFragmentAndImplementsMyInterface> fragment = ...;

你说

  

不幸的是,这在我的特定用例中不起作用,因为有些   这些片段扩展了其他已经实现的片段。

替代(半)解决方案是使用一个边界声明字段,但构造函数中的参数有两个。我说半解决方案,因为在访问Class字段时您将无法获得类型界限。

public enum Something {
    Value1(OneFragmentInterfaceImplementor.class), Value2(
            AnotherFragmentInterfaceImplementor.class);

    public final Class<? extends Fragment> fragment;

    private <T extends Fragment & Interface> Something(final Class<T> fragmentClass) {
        fragment = fragmentClass;
    }
}

如果您可以使用class,则可以声明

public class Example<T extends Fragment & MyInterface> {
    private final Class<T> fragment = ...;
    // ...    
}

答案 1 :(得分:0)

您不能在'diamond'(&lt;&gt;)运算符中传递'implements'子句,因为它只接受类类型。要解决您需要的需求,您可以创建一个类(如果您不希望用户创建此类对象,则创建一个抽象类)来扩展Fragment并实现接口,然后在diamond运算符中传递它。简单地说:

class Holder extends Fragment implements MyInterface // Mark as abstract if user should not instantiate
public final Class<? extends Holder> fragment;