【问题标题】:Using generics for a better way to solve this使用泛型更好地解决这个问题
【发布时间】:2011-12-16 05:27:47
【问题描述】:

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

这里有一些伪代码来概括问题:

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();
    }
}

【问题讨论】:

  • CustomObjectB 和 CustomObjectA 完全不相关吗?
  • 是的,他们的成员完全不同

标签: java generics


【解决方案1】:

你可能想要的是一个通用接口:

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();
    }
}

【讨论】:

  • 完美的例子,谢谢你,立即解决了问题
【解决方案2】:

你需要这样的东西:

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;
    }
}

【讨论】:

    【解决方案3】:
    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();
      }
    }
    

    【讨论】:

      【解决方案4】:

      仅仅使接口通用还不够吗?

      public interface x <T> {
          public Map<String,T> getData()
      }
      

      那么当然类必须实现类似的接口

      public class ClassA implements x<CustomObjectA>
      

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          这样的事情应该会有所帮助:

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

          【讨论】:

            【解决方案7】:

            我的回答可能有点不对劲,因为我不会直接回答你的问题,但它可能是最合适的一个(我不能说清楚,因为你没有详细说明你的课程是做什么的) .

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

            在你的问题中:

            然后在调用getData的实现类中,将它们转换回来 到他们原来的类型。

            听起来不太对劲。您应该在更高的层次上重新考虑您的设计,而不是仅仅尝试使某些部分通用化。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-04-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多