如何从持有孩子的引用的类访问父对象?

时间:2018-03-21 12:28:19

标签: java reference class-diagram

我试图在Java中创建游戏SeaBattle,请参阅下面的类图。

船上的船只的视觉表现通过给船舶覆盖深色的油田的细胞而发生。

为了放置一艘船,我会将它称为段() - 方法并给它它的坐标。为了便于稍后通过点击它所放置的单元格来选择正确的段,我认为最好是单元格包含对同一段的引用。

我所面临的实施问题在于拆除船舶:应该可以根据船舶的指令拆卸船舶(简单:循环通过它的段并取消它们,也移除它们它们所在的单元格中的引用,但也可以通过单击船舶(即:在网格中的其中一个段上)来实现。每当发生这种情况时,我都知道点击了哪个段,但我需要弄清楚该段属于哪个船只,以便取消其他段。

我可以获取单击的单元格坐标,遍历所有船只及其段并检查坐标是否匹配,但我觉得有更好的方法。也许甚至可以更好地设置类图的一部分。

我的班级图: enter image description here

视觉表示的外观示例: enter image description here

1 个答案:

答案 0 :(得分:1)

我们可以将Ship字段添加到ShipSegment,并使ShipSegment成为Cell的子类。这是一个可能的实现:

public class Battlefield {

    Cell[][] cells;

    public Battlefield(int size) {
        this.cells = new Cell[size][size];
        for (int x = 0; x < size; x++) {
            for (int y = 0; y < size; y++) {
                cells[x][y] = new Cell();
            }
        }
    }

    public void add(Ship ship) {
        int start = ship.horizontal ? ship.x : ship.y;
        for (int i = 0; i < ship.size(); i++) {
            cells[ship.horizontal ? i + start : ship.x][ship.horizontal ? ship.y : i + start] = ship.getSegment(i);
        }
    }

    public void remove(Ship ship) {
        int start = ship.horizontal ? ship.x : ship.y;
        for (int i = start; i < start + ship.size(); i++) {
            cells[ship.horizontal ? i : ship.x][ship.horizontal ? ship.y : i] = new Cell();
        }
    }

    public boolean shoot(int x, int y) {
        return cells[x][y].shoot();
    }

}

public class Cell {

    private boolean isShot;

    public Cell() {
        this.isShot = false;
    }

    public boolean isEmpty(){
        return true;
    }

    public boolean isShot(){
        return isShot;
    }

    public boolean shoot() {
        isShot = true;
        return isEmpty();
    }

}

public class ShipSegment extends Cell {

    Ship ship;

    public ShipSegment(Ship ship) {
        super();
        this.ship = ship;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    public Ship getShip() {
        return ship;
    }
}

public class Ship {

    int x, y;
    boolean horizontal;
    ShipSegment[] segments;

    public Ship(int x, int y, int size, boolean horizontal) {
        this.x = x;
        this.y = y;
        this.horizontal = horizontal;
        segments = new ShipSegment[size];
        for (int i = 0; i < size; i++) {
            segments[i] = new ShipSegment(this);
        }
    }

    public int size() {
        return segments.length;
    }

    public boolean isDestroyed() {
        for (ShipSegment segment : segments) {
            if (!segment.isShot()) {
                return false;
            }
        }
        return true;
    }

    public ShipSegment getSegment(int index){
        return segments[index];
    }

}