3

我在学习Java的同时写了一个简单的棋盘,并提出了以下问题:

我有抽象类ChessPiece和类,如King,等QueenRook它们都扩展了ChessPiece

我有一个用于棋盘的 ChessPiece 的 2D 数组。

public ChessPiece myChessBoard[][] = new ChessPiece[8][8];

然后我像这样制作我的棋子:

ChessPiece aPiece = new Rook();

并将其放在 myChessBoard 上,以便我可以找到它:

myChessBoard[0][0] = aPiece;

其他部分也一样...

我的问题是,当我public ChessPiece myChessBoard[][] = new ChessPiece[8][8]; 在第一步中执行此操作时,我使用了 new 关键字并分配了 8*8 = 64 个 ChessPiece 对象,对吗?但是我在写ChessPiece aPiece = new Rook();东西的时候又做了一次,我觉得 myChessBoard[0][0] 之类的东西不需要分配,因为它只是一个参考,不需要像new Rook().

简而言之,我觉得我只需要使用新关键字分配 32 个棋子(棋盘上的 32 个棋子)而不是 32 + 64 = 96 个棋子。

我可能混淆了Java中的一些基本概念,请帮忙。

编辑:

myChessBoard[][] = new ChessPiece[8][8]在这里,我使用 new 关键字创建了 64 个没有真实对象的引用。所以 new 关键字不一定会创建新对象,它也可以创建引用 null 的新引用,对吧?

那是错的。“在这种情况下,新的关键字是创建一个新的二维数组对象”,这要归功于接受的答案。

4

6 回答 6

4

你所做的public ChessPiece myChessBoard[][] = new ChessPiece[8][8];只是初始化一个新的游戏板。棋盘有 64 个方格(每个方格由一个 2D 索引值表示),而不是 64 个棋子。所以每个方块都可以被赋予一个棋子值,比如myChessBoard[0][0] = new Rook();

// or to give your pieces references
Knight blackKnight1 = new Knight();
myChessBoard[0][1] = blackKnight1;

Bishop blackBishop1 = new Bishop();
myChessBoard[0][2] = blackBishop1;

Queen blackQueen = new Queen();
myChessBoard[0][3] = blackQueen;

// and do the rest with all the other pieces according 
// to their position in the 2d array
于 2013-10-20T05:18:21.847 回答
3

这样做时,public ChessPiece myChessBoard[][] = new ChessPiece[8][8];您没有创建单个ChessPiece. 您只创建了一个能够引用 64 ChessPieces 的数组。

所有引用最初都是null,您必须将它们设置为myChessBoard[1][4] = new Rook()

所以没有必要担心。

我假设您的 ChessPiece 类无论如何都是抽象的,因此 Java 无论如何都不可能创建 ChessPiece。

但还有一点:Java 具有自动垃圾收集功能。因此,即使您有时确实创建了一些不必要的对象,垃圾收集器也会很快将其清除。不要过早优化。现在的每台计算机都可以处理 96 或 32 个对象,并且不会有任何明显的区别。

于 2013-10-20T05:18:21.457 回答
1

不,写作new ChessPiece[8][8]不会分配 64 个ChessPiece对象。它只创建一个数组,其中包含 64 个空引用。您需要分别制作ChessPiece对象,这就是您正在做的事情。

请注意,许多 OOP 语言(尤其是 C++)在这方面的工作方式不同。

于 2013-10-20T05:18:01.887 回答
1

public ChessPiece myChessBoard[][] = new ChessPiece[8][8]是一个数组分配语句。它没有分配 64 个新ChessPiece对象,而是一个包含 8*8=64 个对 s 的引用的二维数组ChessPiece,其中大部分是null. 只有 wen 填充每个单独的方格,您才能真正创建一个新ChessPiece对象。

话虽如此,你说得有道理,而且这种分配政策似乎有些浪费。我给你的建议,因为这是一个学习项目 - 将棋盘实现隐藏在它自己的类中(例如,ChessBoard),它现在将包含你的二维数组。一旦其他所有工作都令您满意,您就可以返回并优化ChessBoard.

于 2013-10-20T05:18:11.387 回答
1

当您调用 时ChessPiece myChessBoard[][] = new ChessPiece[8][8];,您没有实例化任何ChessPiece对象。您只是在创建一个可以容纳它们的二维数组。打个比方,当您购买塑料容器来盛放剩余食物时,它们里面并没有食物——您稍后将其放入容器中。

于 2013-10-20T05:18:34.223 回答
1

创建数组时,您只需分配以空值开头的存储单元,但也可用于稍后存储棋子,并创建其中的 64 个。目前还没有棋子。那些仍然需要单独创建。

假设你建造了一个有 10,000 个牢房的监狱。这本身就很棒,但你仍然需要找到 10,000 名囚犯来填充它。

于 2013-10-20T05:18:51.617 回答