【问题标题】:Java polymorphism - getting child command from parent mapJava 多态性 - 从父映射获取子命令
【发布时间】:2018-09-13 10:49:58
【问题描述】:

我开设了两个课程 - BuildingWarehouseWarehouse 扩展 Building。我创建了 Building 映射 (building_map),其中我放置了 Building 对象和 Warehouse 对象。 我想通过地图获取Warehouse的方法,但我只能看到来自Building类的东西。

building_map.get(ware_id);   /*--Warehouse_function--*/;

(这是我在这里的第一篇文章,如果我在我的问题上提供的信息太少,请见谅)

编辑: 以下是我将对象添加到地图中的方式:

        public static Map<String, Building> building_map = new HashMap<>();

Building bD_02 = new Building("bD_02", 2, "Duargian", 2.5, 180, 450, 100, ""
                + "i0_024!i0_029!i0_036?90!10!10!" //upgrade lv 1
                + "&" 
                + "" //upgrade lv 2
                + "&" 
                + "" //upgrade lv 3
                + "&");

Building bD_03 = new Warehouse("bD_03", 3, "Duargian", 2.8, 800, 2500, 1500, 2.35, 3000, ""
                + "i0_021!i0_024!i0_029?200!500!70!" //upgrade lv 1
                + "&" 
                + "" //upgrade lv 2
                + "&" 
                + "" //upgrade lv 3
                + "&");

    building_map.put("bD_02", bD_02);                      
    building_map.put("bD_03", bD_03);                      

编辑2: 谢谢,钨X!成功了,我现在可以结束话题了。

【问题讨论】:

  • 请阅读 java 命名约定:名称中没有 _ 字符(除非是常量)。这不是 python ;-) 请阅读minimal reproducible example 并相应地增强您的问题。你在这里给出的那个例子根本不够,不清楚你在问什么。
  • 请添加您的 building_map 的代码
  • 我用 building_map 的代码更新了问题。
  • 您必须使用instanceof 检查对象的类型并将其转换为Warehouse

标签: java polymorphism parent-child


【解决方案1】:

如果你有一张Buildings 的地图,并不是每个对象都必须有一个Warehouse。它也可以是Building 或其他实现。

如果您确定它是一个仓库,那么您可以像这样投射它:

Map<String, Building> map = new HashMap<>();
map.put("b", new Building());
map.put("w", new Warehouse());

Warehouse w = (Warehouse) map.get("w");
w.yourMethod();

但请记住,有人可以将Bulding 的子对象的另一个实例放入,就像这样

class OtherClass extends Building {}
map.put("b", new Building());
map.put("w", new Warehouse());
map.put("o", new OtherClass());

Warehouse w = (Warehouse) map.get("b");  // ClassCastException
Warehouse w = (Warehouse) map.get("o");  // ClassCastException

PS:正如@Przemyslaw Kruglej 建议的那样,如果您想在运行时中验证泛型集合(如地图)中类的实现,您可以在强制转换之前使用instanceof

Building possibleWarehouse = map.get("w");
if (possibleWarehouse instanceof Warehouse) { // true
    Warehouse warehouse = (Warehouse) possibleWarehouse;
}

【讨论】:

  • +1,但在这种情况下,最好提供一些有关 instanceof 用法的信息,以防止 ClassCastException
  • @PrzemyslawKruglej 是的,我可以,但我不想鼓励这样的编码标准。最好设计一个更好的架构,而不是设计一个糟糕的架构然后instanceof 围绕它:) 你是对的。
  • Danon 当然我理解,但是,instanceof 如果需要,即使使用另一种设计更好,但知道有类似 instanceof 的东西仍然很好;)跨度>
【解决方案2】:

假设您使用 Building 扩展了 Warehouse,您可以将 get 的结果投射到仓库。即class Warehouse extends Building

您的地图如下所示: Map&lt;String, Building&gt; buildingMap = new HashMap&lt;&gt;(); 然后就可以了

更新:安全投射

Building building = buildingMap.get("A");
if (building instanceof Warehouse) {
    ((Warehouse)building).warehousMethod();
}

【讨论】:

  • 如果building_map.get("key")的值是一个Building对象呢?
  • 哦,成功了!谢谢你的帮助,这就是我要找的东西!
  • @JackFlamp 你是对的,我只是举了一个例子 ;-) 总是检查你的对象
  • @FumyaHero 欢迎来到 SO。请选择最适合您的解决方案/答案。
  • 你能在这篇文章中添加安全投射吗?会是最干净的。
【解决方案3】:

map 中的值是建筑类型,所以返回类型 Object 应该是建筑类型。如果作为开发人员,您知道特定键绑定到仓库,则将其类型转换到仓库。 ((仓库) building_map.get("bD_03"))

【讨论】:

  • 在类型转换之前也要注意 null。
猜你喜欢
  • 2011-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
  • 1970-01-01
  • 2017-10-18
相关资源
最近更新 更多