创建一个由能够承载通用值的单元格组成的面板

Create a board made of Cells able host a Generic value

我正在做一个项目(一个游戏),它会有一个可以玩的棋盘。

我想让这个板尽可能通用,以便能够将代码重新用于可能的其他游戏。

public class Board {
    private int rows;
    private int cols;
    private Box[][] board;

    public Board(int rows, int cols){
        Box[][] board = new Box[rows][cols];
        for (int row = 0; row < this.rows; row++){
            for (int col = 0; col < this.cols; col++){
                board[row][col] = new Box();
            }
        }
    }

    public int getCols(){return this.cols;}
    public int getRows(){return this.rows;}

    public Piece getContentAtPos(int row, int col){
        return board[row][col].getContent();
    }
}

这是Boardclass。这里的问题是我必须使用 getContentAtPos() 方法 return 一个 Piece 对象,因为 Box (Cell) class 是这样的:

public class Box {
    private boolean empty;
    private Piece content;

    public Box(){
        empty = true;
    }

    public Box(Piece piece){
        empty = false;
        this.content = piece;
    }

    public boolean isEmpty(){
        return empty;
    }

    public Piece getContent(){
        if (!empty) {
            return content;
        } else {
            return null;
        }
    }
}

然而,对我来说最理想的是 class Box 能够托管任何类型的对象,return 这个通用对象 getContentAtPos() 通过框getContent()方法。

我的通用 Box class.

public class Box<T>{
    private boolean empty;
    private T content;

    public Box(){
        empty = true;
    }

    public Box(T content){
        this.content = content;
        empty = false;
    }

    public boolean isEmpty(){
        return empty;
    }

    public T getContent(){
        if (!isEmpty()){
            return content;
        }
        return null;
    }

    public T setContent(Object content){
        this.content = content;
    }
}

但是我需要在看板中更改什么 class?

我应该在其中输入什么 return 值?

您应该创建一个接口,您将来 class return 将实现该接口。这样你就可以确定 return 类型将实现接口并定义行为。

    public interface ReturnableBox { 
          public boolean isEmpty();
    }
    public class Board {

       private int rows;
       private int cols;
       private ReturnableBox [][] board;
   }
   public class Box implements ReturnableBox {
   //...
   }

the ideal for me would be the class Box to be able to host any type of object and return this generic object with getContentAtPos via the Box getContent method

我猜您希望您的游戏组件声明某种行为。如果是这样,Box 不需要存储任意对象,而是表示包含游戏块预期具有的所有方法的合同类型的对象。

换句话说,你可以定义一个接口,比方说Piece,它将有几个实现:

public interface Piece {
    // behavior of game pieces
}

public class MyGamePiece implements Piece {
    // implementations
}

您不需要使 Box class 成为泛型,它可以包含 Piece:

类型的字段
public class Box {
    private boolean empty;
    private Piece content;
    
    // constractor and methods

    public void setContent(Object content){
        this.content = content;
    }

    public Piece getContent(){
        return content;
    }
}

这使您可以自由地通过 Box class 的构造函数提供 Peice 的任何实现或 setter。这意味着你可以设计 gave 的核心部分只有一个实现 MyGamePiece,然后再添加一些 class 像 NewGamePeace (名称应该反映 class如果是简洁明了的方式,那只是虚拟示例)。

关键是您可以从 polymorphism 中受益,而不必更改以前设计和测试的代码以使其与新的 classes(称为后期绑定):

Box box = new Box();
box.setContent(new MyGamePiece());
box.setContent(new NewGamePeace()); // in order to make this line compile only need to introde the `NewGamePeace` class itself

方法 getContentAtPos() 也将 return 类型为 Piece 的对象。

I want to make this board as generic as possible in order to be able to re-use the code for a possible other game.

这是一个值得称赞的目标。

您的 classes 必须是 loosely coupled and narrow focused 才能重复使用。 IE。每个 class 都应该是一个狭窄的 well-defined 功能集,并且只知道那些对其工作至关重要的对象(减少耦合)。

并且可以让必要的耦合松散(高耦合不好,但是class没有耦合就根本无法交互,需要保持平衡) 通过引入如上所示的接口。

即使您最终不会在其他项目中使用此代码,保持松散耦合也是有益的,因为这样可以更轻松地维护和扩展代码。