【问题标题】:Accessing subclass-methods in ArrayList from ParentClass从 ParentClass 访问 ArrayList 中的子类方法
【发布时间】:2014-04-14 17:31:11
【问题描述】:

目前我的班级看起来像这样(非常简化):

我有三个类来描述节点或方式(来自 OpenStreetMap):

public abstract class Geometry {
    private String id;

    public Geometry(String id) {
        this.id = id;
    }
}

public class Node extends Geometry {
    private GeoPoint location;

    public Point(String id, GeoPoint location) {
        super(id);
        this.location = location;
    }
    public GeoPoint getLocation() {
        return location;
    }
}


public class Ways extends Geometry {
    private ArrayList <GeoPoint> shape;

    public Point(String id, ArrayList <GeoPoint> shape) {
        super(id);
        this.shape = shape;
    }
    public GeoPoint getShape() {
        return shape;
    }

}

现在我想用类 Geometry 遍历一个 ArrayList 并使用两个子类中的方法:

private void prepareList(ArrayList<Geometry> geometries) {
    for (Geometry m : geometries) {
         if (m.getClass().equals(Node.class)) {
             location = m.getLocation();
         }
         else if (m.getClass().equals(Way.class)) {
             shape = m.getShape();
         }
    }
}

在我的解决方案中,我需要在 Geometry 类中创建一些虚拟方法来访问这些方法,例如 公共地理点getLocation(){ 返回空值; }

我现在的问题是,在 Java 中实现这一点的最佳方法是什么,而不需要创建单独的类(这会导致代码重复)或编写这个“虚拟”方法。有没有更好的办法?

【问题讨论】:

  • instanceof 是你的朋友。我确实阅读了您的问题 3 次,很抱歉,但我不明白。您能否详细说明(您在说什么虚拟方法)?也许您应该发布您拥有的代码(使用虚拟方法)
  • 如果您要对几何进行类型检查,您可以对其进行类型转换并调用适当的方法。即:if (m instanceof Node) { location = ((Node)m).getLocation() } 虽然我不确定这是否是最好的设计。最好看看能不能做一个两个类都实现的抽象方法。
  • 如果可能的话,我会避免使用 instanceof。这是一个很好的迹象,表明您不是在编写 OO
  • 您可以考虑使用此帖子link 的答案中描述的访问者模式。我认为这可能是最好的选择。
  • @Amir 我完全同意,这基本上就是他最初所做的。这就是我链接访客模式的原因。

标签: java inheritance


【解决方案1】:

如果我正确理解了您的问题,您可以简单地在 Geometry 上声明一个 abstract 方法,该方法由 NodeWays 子类实现。

public abstract class Geometry {
    private String id;

    public Geometry(String id) {
        this.id = id;
    }

    public abstract GeoPoint getLocation();
}

或考虑将 Geometry 设为接口。比如:

public interface Traversable { 

    public String getId();

    public GeoPoint getLocation();

}

并在WaysNodes 上实现此接口。我更喜欢后一种方法,因为一个类可以实现多个接口,但只能扩展一个超类。

编辑: 现在我更清楚一点,您不会从WaysNodes 返回相同的东西。你可以:

  • 将结果包装在一个可以处理单个GeoPointListGeoPoints 的类中
  • 重新编写此代码以执行 WayNode 需要在子类内部执行的任何操作。
  • 使用GeoPoints的List作为方法的返回类型,一个节点只有一个元素返回,而Way返回的点很多

【讨论】:

  • Ways 不使用 getLocation,它使用返回 GeoPoints 的 ArrayList 的 getShape。我也在想这个,但在这种情况下不会起作用。
  • 我明白你的意思 Luuk。听起来这应该是他们各自执行的操作。或者他需要一个封装接口方法返回值的类。
  • 感谢您的回答。也许为了更好的理解:我从 OpenStreetMap 服务器接收到一个带有路径和节点的 XML 文件,并解析这个文件以找到所有相关的几何并将它们保存在 ArrayList 中。 Way 和 Node 类共享大约 60% 的属性,这就是我使用父类几何图形的原因。然而,该类的另一部分(子类中的方法,例如 getLocation)对这些类不是很有用。要在解析几何列表时访问这些方法,我不得不在父类中编写“虚拟”方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 2017-09-26
  • 2017-09-22
相关资源
最近更新 更多