所以,这可能是也可能不是你的想法,我不完全确定我已经正确地提出了这个问题,但是我们走了!我正在建立一个国际象棋游戏,我正在尝试动态我如何调用我的类,构建片段,并将它们设置在板上。
向下看代码:我读了一个包含诸如“pla1”之类的文件的文件,表示一个部分,它的颜色,它的x坐标和它的y坐标。在这个例子中,p = pawn,l = white,a =板上的x坐标,1 =板上的y坐标。这样:
“白色棋子在a1”
简单。现在,我有一个片段类来解析文件中的片段,以及一个名为“Pawn”的特定类,所以当我想要向棋盘添加一个片段时,该片段有自己的类来控制它的移动能力和开启功能国际象棋棋盘等。
问题:我无法弄清楚如何动态设置我的作品类。我可以使用硬编码版本轻松完成此操作,您可以在评论中看到,或者使用if声明。是否可以使用我的字符串变量设置我的类?
我的代码如下:
//reads from the file, puts each line into an arraylist
public void readFromFile(String fileName) throws IOException
{
String line;
BufferedReader br = new BufferedReader(new FileReader(fileName));
//adds line to arraylist
while((line = br.readLine()) != null)
fileLines.add(line.toLowerCase());
//send each line in the list to method
for(String item : fileLines)
buildPiecesFromFileAndGetLocation(item);
}
ChessPiece[][] pieces = new ChessPiece[9][9]; my chessboard
String spawnPiece;
String spawnColor;
String pieceRepresentation;
String originx;
int originX;
int originY;
public void buildPiecesFromFileAndGetLocation(String item)
{
//regex matcher // using this to match it: Pattern copyPiece = Pattern.compile("(?<piece>q|k|b|p|n|r+)(?<color>l|d)(?<x>\\w)(?<y>\\d)");
Matcher copyMatcher = copyPiece.matcher(item);
//hashmap for matching quicker; currently only has pieceMatches.put("p", "Pawn") within it
hashIdentities();
if (copyMatcher.find())
{
spawnPiece = pieceMatches.get(copyMatcher.group("piece")); //spawnPiece becomes "Pawn"
spawnColor = colorMatches.get(copyMatcher.group("color"));
pieceRepresentation = spawnPiece + spawnColor;
originx = copyMatcher.group("x"); //change letter to number
transferChars(); //changes letter "a" into integer "1"
originY = Integer.parseInt(copyMatcher.group("y")); //string to int
//PROBLEM:
pieces[originX][originY] = new spawnPiece(pieceRepresentation); //since spawnPiece is now "Pawn" i want it to be able to call a new instance of the class Pawn. this way doesn't work. Solution?
//logic:
//pieces[a][b] = new (WHATEVER PIECE WAS MATCHED)("position + color");
//hardcoded version:
//pieces[1][1] = new Pawn("PawnWhite");
}
}
我不确定这是否可行。任何帮助将不胜感激,如果需要任何详细的代码我可以提供。
答案 0 :(得分:2)
使用工厂类。
interface ChessPieceFactory {
ChessPiece create(String pieceName);
}
class ChessPieceFactoryImpl {
public ChessPiece create(String pieceName) {
if("pawn".equals(pieceName))
return new Pawn(pieceName);
throw new IllegalArgumentException(pieceName);
}
}
答案 1 :(得分:0)
看看这篇文章:http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html
直接引用它:
有两种用于创建类实例的反射方法: java.lang.reflect.Constructor.newInstance()和Class.newInstance()。 前者是优选的,因此在这些例子中使用,因为:
- Class.newInstance()只能调用零参数构造函数, 而Constructor.newInstance()可以调用任何构造函数,无论如何 参数数量。
- Class.newInstance()抛出任何异常 由构造函数抛出,无论是否被检查或 选中。 Constructor.newInstance()始终包装抛出的异常 使用InvocationTargetException。
- Class.newInstance()需要 构造函数是可见的; Constructor.newInstance()可以调用 私人施工人员在某些情况下。
醇>
让我为你添加一些代码。首先,您需要获取要创建其实例的类的引用。您已经拥有该类的名称,所以这样做:
Class pieceKlass = Class.forName(spawnPiece)
然后获取其构造函数,该构造函数接受单个字符串并创建该类的实例:
Constructor ctor = pieceKlass.getDeclaredConstructor(String.class);
ctor.setAccessible(true);
ChessPiece piece = (ChessPiece)ctor.newInstance(pieceRepresentation);
鉴于这段代码非常复杂并且需要一些错误处理,您现在可以整齐地在工厂类中提取它:
class ChessPieceFactory {
public ChessPiece create(String pieceName, String pieceRepresentation) {
ChessPiece piece;
try {
Class pieceKlass = Class.forName(pieceName)
Constructor ctor = pieceKlass.getDeclaredConstructor(String.class);
ctor.setAccessible(true);
piece = (ChessPiece)ctor.newInstance(pieceRepresentation);
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (InvocationTargetException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
}
return piece;
}
由于您还使用Chess标记标记了问题,我应该指出您应该使用标准Forsyth-Edwards Notation来填充国际象棋棋盘。它使用大写字母表示白色字母,小写字母表示黑色字母。