【问题标题】:Why can I declare an object which is of the type of an interface, and instantiate this object as another type?为什么我可以声明一个接口类型的对象,并将这个对象实例化为另一种类型?
【发布时间】:2012-11-05 03:45:20
【问题描述】:

我是 Java 和 Android 的新手。我想了解以下行:

List<Map<String, String>> listMap = new ArrayList<Map<String, String>>();

我的疑问是:它声明了一个名为 listMap 的对象,它是 Map 的 List 类型,对吧?但它被实例化为一个 ArrayList。很抱歉这个简单的问题,但为什么会这样?

ps1:我知道List是一个接口,所以我不能实例化一个接口类型的对象。

ps2:我可以将 listMap 声明为 ArrayList 类型。将其声明为 List 有什么好处。

【问题讨论】:

标签: java android list arraylist


【解决方案1】:

ps1:我知道 List 是和接口,所以我不能实例化它的类型和对象。

List<Map<String, String>> listMap = new ArrayList<Map<String, String>>();

你是对的,List 是一个接口,因此你不能实例化一个接口。您需要使用接口的一些实现类来实例化。 ArrayList是接口List的实现类,在able语句中使用。

ps2:我可以将 listMap 声明为 ArrayList 类型。将其声明为 List 有什么好处。

您也可以在左侧使用ArrayList,即

  ArrayList<Map<String, String>> listMap = new ArrayList<Map<String, String>>();

使用接口的优势:如果你想跨类使用你的变量对象(listMap)那么最好使用接口作为类型,但是如果你的变量对象(lsitMap) 在你的程序本地本地,那么我认为没有任何额外的优势。

现在你会想到Map,它又是一个接口。请注意,您没有通过上述语句实例化 Map 对象。您只是提到您的listMap 列表将包含Map 类型的元素。

当您尝试实例化要添加到listMap 中的元素时,您将需要Map 接口的实现类,例如HashMap,如下所示:

   List<Map<String, String>> listMap = new ArrayList<Map<String, String>>();

   Map<String, String> lsitMapElement1 = new HashMap<String, String>();
   lsitMapElement1.put("key1", "value1");
   listMap.add(lsitMapElement1 );

   Map<String, String> lsitMapElement2 = new HashMap<String, String>();
   lsitMapElement2.put("key2", "value2");
   listMap.add(lsitMapElement2);

希望这能让事情变得清晰。

【讨论】:

  • 好的。谢谢你。但我可以将 listMap 声明为 ArrayList 类型。将其声明为 List 有什么好处。
  • @user1771682 我已经在更新答案了。请参考答案顶部添加的新段落。
  • 谢谢。很好的解释。我已经在我的代码中使用了 HashMap。
  • 完成!真的,我认为我的情况没有优势。我的应用程序只是一个例子,这个变量只在主活动类中使用。所以我认为它被声明为 List 只是由于良好的编程习惯。再次感谢您。
  • " 但是如果您的变量对象 (lsitMap) 在本地程序中本地,那么我认为没有任何额外的优势”。 public void myMethod(List&lt;MyObject&gt; list),请记住 list 是本地的。如果您要在那里使用ArrayList,那么您将不得不更改您的方法签名。所以,我不会认为这是一个坏建议。
【解决方案2】:

ArrayListList 的子类型。那是一个ArrayList is-a List

您可以将子类型的实例分配给它的超类型的变量。或者,在需要超类型 some 的情况下,您可以将其替换为 some substype 。


您可以通过它实现对象多态性(通过继承),并且您的代码不依赖于某些特定的实现。而是在未来的任何时候,如果您突然意识到 ArrayList 不起作用并且您需要 List 的其他实现,那么您可以轻松切换到该实现而不影响其余代码。

这就是他们说“尽可能始终针对接口编写代码”的原因。

【讨论】:

  • 好的。谢谢你。但我可以将 listMap 声明为 ArrayList 类型。将其声明为 List 有什么好处
【解决方案3】:

ArrayList类实现了List接口,也就是说List定义的所有方法都已经实现了。其他代码不需要知道这是一个具体的ArrayList,只需它实现了所有List 方法即可。

【讨论】:

  • 好的。谢谢你。但我可以将 listMap 声明为 ArrayList 类型。将其声明为 List 有什么好处
  • 您的ArrayList 对象恰好包含Map 对象,但它仍然会实现List 的所有方法。您可以使用另一个实现 List 的对象,只要它提供了您需要的特定功能。
猜你喜欢
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
  • 2020-12-05
相关资源
最近更新 更多