Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用泛型可以更好地解决这个问题_Java_Generics - Fatal编程技术网

Java 使用泛型可以更好地解决这个问题

Java 使用泛型可以更好地解决这个问题,java,generics,Java,Generics,我很确定我可以用Java泛型解决这个问题,所以我想问一下……假设我有几个类,每个类都实现一个公共接口,公共接口中有一个方法叫做getData,我想把它变成泛型。我遇到的问题是,每个类返回不同的对象类型,因此理想情况下,我希望这些对象类型是泛型的,然后在调用getData的实现类中,将它们转换回原始类型。如果我将强制转换为对象并返回到特定类型,我可以看到这将如何工作,但是我可以用泛型实现相同的最终结果吗 下面是一些伪代码来概述问题: public ClassA implements interfa

我很确定我可以用Java泛型解决这个问题,所以我想问一下……假设我有几个类,每个类都实现一个公共接口,公共接口中有一个方法叫做
getData
,我想把它变成泛型。我遇到的问题是,每个类返回不同的对象类型,因此理想情况下,我希望这些对象类型是泛型的,然后在调用
getData
的实现类中,将它们转换回原始类型。如果我将强制转换为
对象
并返回到特定类型,我可以看到这将如何工作,但是我可以用泛型实现相同的最终结果吗

下面是一些伪代码来概述问题:

public ClassA implements interface x {

    private CustomObjectA customObjectA;
    private Map<DateTime, Map<String, CustomObjectA>> dataMap;

...

    public Map<DateTime, Map<String, CustomObjectA>> getData() {
        return this.dataMap;
    }
}

public ClassB implements interface x {

    private CustomObjectA customObjectB;
    private Map<DateTime, Map<String, CustomObjectB>> dataMap;

...

    public Map<DateTime, Map<String, CustomObjectB>> getData() {
        return this.dataMap;
    }
}

public interface x {
    public Map<DateTime, Map<String, genericObject>> getData();
}


public ClassC {
    public testGeneric(x objX) {

        CustomObjectA cOA = objX.getData();
        CustomObjectB cOB = objX.getData();
    }
}
public ClassA实现接口x{
私有CustomObjectA CustomObjectA;
私有地图数据地图;
...
公共地图getData(){
返回此.dataMap;
}
}
公共类B实现接口x{
私有CustomObjectA customObjectB;
私有地图数据地图;
...
公共地图getData(){
返回此.dataMap;
}
}
公共接口x{
公共地图getData();
}
公共C类{
公共测试通用(x objX){
CustomObjectA cOA=objX.getData();
CustomObjectB cOB=objX.getData();
}
}

仅仅使接口通用还不够吗

public interface x <T> {
    public Map<String,T> getData()
}
公共接口x{
公共地图getData()
}
当然,这些类必须实现如下接口

public class ClassA implements x<CustomObjectA>
公共类ClassA实现x

让CustomObjectA和CustomObjectB扩展一个公共超类。然后,将界面中的方法声明修改为:

public Map<DateTime, Map<String, ? extends CustomObjectSuperclass>> getData();
publicmap getData();

您需要这样的东西:

public interface X<T> {
    Map<Date, Map<String, T>> getData();
}

public class ClassA implements X<CustomObjectA> {

    private CustomObjectA customObjectA;
    private Map<DateTime, Map<String, CustomObjectA>> dataMap;

...

    public Map<DateTime, Map<String, CustomObjectA>> getData() {
        return this.dataMap;
    }
}

public class ClassB implements X<CustomObjectB> {

    private CustomObjectB customObjectB;
    private Map<DateTime, Map<String, CustomObjectB>> dataMap;

...

    public Map<DateTime, Map<String, CustomObjectB>> getData() {
        return this.dataMap;
    }
}
公共接口X{
映射getData();
}
公共类ClassA实现了X{
私有CustomObjectA CustomObjectA;
私有地图数据地图;
...
公共地图getData(){
返回此.dataMap;
}
}
公共类B实现了X{
私有CustomObjectB CustomObjectB;
私有地图数据地图;
...
公共地图getData(){
返回此.dataMap;
}
}

您可能需要的是一个通用接口:

public interface X<T> {
    Map<DateTime, Map<String, T>> getData();
}

public class A implements X<CustomObjectA> {
    @Override
    public Map<DateTime, Map<String, CustomObjectA>> getData() {
        ...
    }
}

public class B implements X<CustomObjectB> {
    @Override
    public Map<DateTime, Map<String, CustomObjectB>> getData() {
        ...
    }
}

public class C {
    public static void main(String[] args) {
        X<CustomObjectA> a = new A();
        Map<DateTime, Map<String, CustomObjectA>> m1 = a.getData();
        X<CustomObjectB> b = new B();
        Map<DateTime, Map<String, CustomObjectB>> m2 = b.getData();
    }
}
公共接口X{
映射getData();
}
公共类A实现了X{
@凌驾
公共地图getData(){
...
}
}
公共类B实现了X{
@凌驾
公共地图getData(){
...
}
}
公共C类{
公共静态void main(字符串[]args){
xa=新的a();
Map m1=a.getData();
xb=新的b();
Map m2=b.getData();
}
}

类似的内容应该会有所帮助:

public interface GenericObject<T> {
    public Map<DateTime, Map<String, T>> getData();
}

public class ClassA implements GenericObject<CustomObjectA> {
    public Map<DateTime, Map<String, CustomObjectA>> getData() {
        // ...
    }
}

public class ClassB implements GenericObject<CustomObjectB> {
    public Map<DateTime, Map<String, CustomObjectB>> getData() {
        // ...
    }
}
公共接口通用对象{
公共地图getData();
}
公共类ClassA实现GenericObject{
公共地图getData(){
// ...
}
}
公共类ClassB实现GenericObject{
公共地图getData(){
// ...
}
}
导入java.util.Calendar;
导入java.util.Map;
公共类泛型示例{
公共静态接口X{
公共地图getData();
}
公共静态类A实现了X{
私有地图数据地图;
公共地图getData(){
返回此.dataMap;
}
}
公共静态类B实现了X{
私有地图数据地图;
公共地图getData(){
返回此.dataMap;
}
}
公共静态void main(字符串[]args){
xa=新的a();
xb=新的b();
Map longData=a.getData();
Map doubleData=b.getData();
}
}

我的答案可能有点不对劲,因为我不会直接回答你的问题,但它可能是最合适的答案(我真的说不出来,因为你没有给出你的类做什么的太多细节)

如果CustomObjectA和CustomObjectB实际上完全不相关,那么不要为
getData
方法定义接口。该方法为ClassA和ClassB返回完全不同的结果,将它们分组在同一接口下没有多大意义。您仍然可以使用ClassA.getData()和ClassB.getData(),但您永远无法在同一段代码中使用继承来使用这两种方法。但无论如何它都不应该发生,因为getData返回的内容在这两种情况下是完全不同的

在你的问题中:

然后在调用getData的实现类中,将它们转换回 恢复到原始类型


听起来不对。您应该在更高的层次上重新思考您的设计,而不仅仅是尝试制作一些通用零件。

CustomObjectB和CustomObjectA是否完全不相关?是的,它们有完全不同的membersPerfect示例,谢谢,这会立即解决问题
import java.util.Calendar;
import java.util.Map;


public class GenericsExample {

  public static interface X<T> {
    public Map<Calendar, Map<String, T>> getData();
  }

  public static class A implements X<Long> {
    private Map<Calendar, Map<String, Long>> dataMap;
    public Map<Calendar, Map<String, Long>> getData() {
        return this.dataMap;
    }
  }

  public static class B implements X<Double> {
      private Map<Calendar, Map<String, Double>> dataMap;
      public Map<Calendar, Map<String, Double>> getData() {
          return this.dataMap;
      }
  }

  public static void main(String[] args) {
    X<Long> a = new A();
    X<Double> b = new B();
    Map<Calendar, Map<String, Long>> longData = a.getData();
    Map<Calendar, Map<String, Double>> doubleData = b.getData();
  }
}