具有多种类型支持的Java Generics

时间:2011-05-09 21:41:12

标签: java generics polymorphism abstract-class

假设我们有一个接口......

interface ICalculator<T extends CalculableObject>{ void calculate(T obj); }

我们的泛型类型是一个抽象类......

public abstract class CalculableObject{...}

有多种具体类型......

public class TypeA extends CalculableObject{...}

public class TypeB extends CalculableObject{...}

如何定义Calculator对象的实现,该实现需要为多个CalculableObject类型定义计算方法?

即 -

public CalculatorAB<?> implements ICalculator{
void calculate(TypeA obj){...}
void calculate(TypeB obj){...}
}

5 个答案:

答案 0 :(得分:2)

由于类型擦除,你不能。请参阅:Getting error for generic interface: The interface Observer cannot be implemented more than once with different arguments:

我要做的是使用delgate并使用您的CalculatorAB,但它只是没有实现ICalculator,或者更好的是,让CalculatorAB实现ICalcuator。然后,您的方法可以检查实例并转发到适当的方法。

public CalculatorAB implements ICalculator<CalculableObject> {
  void calculate(CalculableObject obj){
    if(obj instanceof TypeA)
      calculate((TypeA)obj);
    else if(obj instanceof TypeB)
      calculate((TypeB)obj);
  }
  void calculate(TypeA obj){...}
  void calculate(TypeB obj){...}
}

答案 1 :(得分:1)

你做不到。 (与普遍看法相反,它可以相对容易地在没有运行时具体化的情况下实现。但事实并非如此。)

通常,“主要”类型的多个子类型是一个坏主意。有一个对象具有返回适当Calculator的方法(请不要匈牙利语!)。

答案 2 :(得分:0)

使用enum

public enum Type extends CalculableObject {
    A
    {
        @Override
        public void doSomething() { }
    },
    B;
}

然后我们保证Type的{​​{1}}和A存在,并且它们都延伸B

这使您只需将CalculableObject方法作为Type.A calculate传递给Type方法,而不是将其与A,B,C,D等

答案 3 :(得分:0)

我敢说,如果你想这样做,也许在你的设计的其他地方出现了问题。但除了已经提到的替代方案之外,您可以在接口中仅使计算方法通用,而不是整个接口。然后子接口可以是通用的,或者只是定义你想要的新方法。

像这样:

public static abstract class CalculableObject{}

public static class TypeA extends CalculableObject{}
public static class TypeB extends CalculableObject{}
public static class TypeC extends CalculableObject{}

public interface ICalculator{
    <T extends CalculableObject> void calculate(T obj);
}

public static class CalculatorAB implements ICalculator{

    void calculate(TypeA obj){
        System.out.println("TypeA");
    }
    void calculate(TypeB obj){
        System.out.println("TypeB");
    }

    @Override
    public <T extends CalculableObject> void calculate(T obj) {
        System.out.println("CalculableObject");
    }
} 

public static void main(String args[]){
    TypeA a = new TypeA();
    TypeB b = new TypeB();
    TypeC c = new TypeC();

    CalculatorAB ab = new CalculatorAB();

    ab.calculate(a);
    ab.calculate(b); 
    ab.calculate(c);
}

这呈现

TypeA
TypeB
CalculableObject

答案 4 :(得分:-1)

您可以在CalculableObject类中定义“计算”所需的方法。然后,在CalculatorAB中,您只需在给定对象上调用这些方法。