Java开发JailBreak时无法引用AbstractGamePiece的getPlayerType()方法问题
问题解答:为什么无法正确调用
getPlayerType()方法 现有开发上下文
业务规则要求
当用户点击方格时,需要按顺序完成两层校验后才能触发选中高亮:
- 首先判断方格上是否存在棋子,即校验条件
clickedSquare.getPiece()!= null - 其次校验棋子归属:通过
getPiece()返回的AbstractGamePiece对象调用getPlayerType()获取棋子所属玩家类型,与JailBreak类的当前回合变量currentPlayerTurn做比对 - 校验通过后,将选中方格设为当前点击方格,调用方格的
select()方法显示黄色边框
当前开发现状
- 已独立完成
select()方法的高亮效果实现,但多次尝试实现归属校验时,始终无法正确调用getPlayerType()方法 - 已验证:当前类可以正常访问
AbstractGamePiece的静态成员,比如已跑通的回合切换方法:
private void changePlayerTurn() { if (currentPlayerTurn == AbstractGamePiece.PLAYER_OUTLAWS) currentPlayerTurn = AbstractGamePiece.PLAYER_POSSE; else currentPlayerTurn = AbstractGamePiece.PLAYER_OUTLAWS; }
- 此前的错误尝试包括:直接编写
AbstractGamePiece.getPlayerType()==currentPlayerTurn作为判断条件、嵌套if校验棋子存在性时调用方法失败、尝试直接实例化抽象类(但该抽象类构造器需要3个与当前场景不匹配的参数,逻辑完全不成立) - 目前已实现的
handleClickedSquare()方法存在无差别高亮任意点击方格棋子的问题,未加入归属校验逻辑:
private void handleClickedSquare(GameSquare clickedSquare) { if (selectedSquare == null) { selectedSquare=clickedSquare; selectedSquare.select(); } else if (selectedSquare == clickedSquare) { selectedSquare.deselect(); selectedSquare = null; } else { } }
关联抽象类定义参考
abstract public class AbstractGamePiece { // 两队标识常量 static public final int PLAYER_OUTLAWS = 0; static public final int PLAYER_POSSE = 1; // 棋子位置属性 protected int myCol; protected int myRow; // 棋子所属玩家类型属性 protected int myPlayerType; // 棋子名称与缩写属性 private String myAbbreviation; private String myName; // 子类必须实现的转义判定逻辑 abstract public boolean hasEscaped(); // 抽象类构造器 public AbstractGamePiece(String name, String abbreviation, int playerType) { myName = name; myAbbreviation = abbreviation; myPlayerType = playerType; } // 实例方法:获取棋子所属玩家类型 public int getPlayerType() { return myPlayerType; } // 其他通用棋子方法实现 public void setPosition (int row, int col) { myRow = row; myCol = col; } public int getRow() { return myRow; } public int getCol() { return myCol; } public String getAbbreviation() { return myAbbreviation; } public String toString() { return (myName + " at " + "(" + myRow + "," + myCol + ")"); } public boolean canMoveToLocation(List<GameSquare> path) { return false; } public boolean isCaptured(GameBoard gameBoard) { return false; } }
问题根因
调用失败的核心原因是混淆了静态成员与实例成员的调用规则:
getPlayerType()是定义在AbstractGamePiece上的实例方法,必须通过该类的具体实例对象调用,不能直接用类名AbstractGamePiece.getPlayerType()的方式调用。你之前写的这类语法,本质是将实例方法错当成静态方法调用,编译器会直接报错。- 之前能正常访问
AbstractGamePiece.PLAYER_OUTLAWS这类常量,是因为这些常量本身就是static修饰的静态成员,和实例方法的调用逻辑完全独立,不能因为静态成员可以正常用类名访问,就推断所有类的成员都支持这种调用方式。 - 完全不需要手动实例化
AbstractGamePiece抽象类:当clickedSquare.getPiece()返回非空值时,拿到的本身就是一个已经初始化完成的AbstractGamePiece具体子类对象,直接对这个对象调用实例方法即可。
正确实现参考
按照业务规则补全校验逻辑后的handleClickedSquare()方法示例:
private void handleClickedSquare(GameSquare clickedSquare) { // 校验1:点击方格无棋子,直接返回不处理 if (clickedSquare.getPiece() == null) { return; } // 校验2:棋子不属于当前回合玩家,直接返回不处理 AbstractGamePiece clickedPiece = clickedSquare.getPiece(); if (clickedPiece.getPlayerType() != currentPlayerTurn) { return; } // 原有选中/取消选中逻辑保持不变 if (selectedSquare == null) { selectedSquare=clickedSquare; selectedSquare.select(); } else if (selectedSquare == clickedSquare) { selectedSquare.deselect(); selectedSquare = null; } else { } }
内容的提问来源于stack exchange,提问作者Meezy98
相关产品推荐
相关产品推荐

