在Java泛型中有没有办法说" T扩展Thing或T扩展SomethingElse"?

时间:2014-10-04 20:48:08

标签: java generics

在Java中,我可以说class SomeClass<T extends Thing>。但有没有办法说我希望T延长ThingSomethingElse

4 个答案:

答案 0 :(得分:1)

无法在Java中执行此操作 - Java不支持algebraic data types

Java通用类型限制必须将统一到单个类型,就像Java 中的表达式必须将统一到单个类型一样 - 例如。由于与尝试使用 1

相同的原因,它无效
{ArrayList | HashSet} collection = ..;

但是,由于这两种类型的统一,因此以下内容有效:

Collection collection = createArrayListOrHashSetAndReturnACollection();

现在,根据需要,有两种常规方法可以处理任务 ,这两种方式都可以回到上述限制:

  1. 有问题的类型可以从常见类型扩展(或更好地继承),然后可以统一围绕该类型。这可能涉及根据需要修改相关类型。

  2. 可以创建一个不同的类型(由接口支持,可能使用合成),作为Thing / SomethingElse类型的代理。现在,统一这个新类型/接口的通用限制。

  3. 删除对象周围的类型限制和统一;这是Java中每个非原始类型的最不精确的统一。


  4. 1 虽然这不是“OOP”,泛型/模板或静态类型系统的限制,但 Java的工作方式:nope,can不这样做。

答案 1 :(得分:1)

事实上,Java中有一种非常着名的代数数据类型编码。它被称为访客模式。甚至还有一个编译时解决方案来简化此模式的实现:请参阅Github上的项目adt4j。

但你要找的是Generalized algebraic data type (GADT)

事实证明,Java也支持GADT(并且没有类型转换)。请参阅此要点,作为使用GADT表达问题的优雅解决方案的示例:https://gist.github.com/jbgi/208a1733f15cdcf78eb5 - 在此代码中,我们定义了类,其中T被静态约束为整数或布尔值。

答案 2 :(得分:-1)

你可以这样做

public abstract class SomeClass<T>{

}

public class StringSomeClass : SomeClass<String>{

}

public class IntegerSomeClass : SomeClass<Integer>{

}

答案 3 :(得分:-4)

不,没有。在每个面向对象的语言中,类只能扩展一个类。

相反,你可能想要使用类似的东西:
MyClassOne扩展了Something
MyClassTwo扩展了SomethingElse

if(...)
MyClassOne
否则
MyClassTwo