繁体   English   中英

具有多种类型支持的Java Generics

[英]Java Generics with multiple type support

假设我们有这样的界面......

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

因为类型擦除,你不能。 请参阅: 获取通用接口的错误:接口Observer不能使用不同的参数多次实现:

我要做的是使用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){...}
}

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

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

使用enum

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

然后保证TypeAB存在,并且它们都扩展了CalculableObject

这也使您能够简单地在传递Type.Acalculate方法作为Type CalculableObject ,而不是与A,B,C,d,等等弄乱它

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

像这样:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM