java - 在简单的Java程序中努力应用继承概念
问题描述
我想动态地将其超类类型的变量声明为子类,但我不确定如何。
该程序是一个有用户和 NPC 的纸牌游戏:
public class Player {
private int playerNumber;
public Player(int playerNumber) {
this.playerNumber = playerNumber;
}
}
public class User extends Player {
public User(int playerNumber) {
super(playerNumber);
}
public void clickInteraction() {...}
}
public class NPC extends Player {
private Hand hand;
private int playerNumber;
private int score ;
private Actor scoreActor;
IFilterBehaviour filterBehaviour;
ISelectBehaviour selectBehaviour;
public NPC(int playerNumber, IFilterBehaviour filterBehaviour, ISelectBehaviour selectBehaviour){
super(playerNumber);
this.filterBehaviour = filterBehaviour;
this.selectBehaviour = selectBehaviour;
this.hand = null;
this.playerNumber = playerNumber;
}
//strategy pattern filter
//@Override
public ArrayList<Card> filter(Hand hand, Hand trick, Whist.Suit trumps) {...}
//strategy pattern select
//@Override
public Card select(ArrayList<Card> hand, Hand trick, Whist.Suit trumps) {...}
}
我想跟踪谁在播放器类型下玩,因为相同的规则适用于 NPC 和用户,所以我尝试使用这样的东西:
Player nextPlayer = playersArray(random.nextInt(nbPlayers))
我希望能够使用其中之一的方法,NPC
但User
显然我不能使用 nextPlayer.filter 当 filter 是 NPC 方法时。我可以做这样的事情吗?
if (playersArray(random.nextInt(nbPlayers)) instance of npc) {
nextPlayer be treated as npc
}
else { nextPlayer be treated as user }
解决方案
如果您想在两种类型的播放器上调用相同的方法,请声明Player
为 aninterface
以及您希望子类实现的任何方法...如果您希望每种类型的播放器都有playerNumber
/ playerId
,请使用另一个抽象类PlayerId
,其中包含您的字段想。
在我看来,您已经NPC
声明了自己的playerNumber
(已在父类中声明)Player
。这是多余的,可以删除。
除非您需要“向下转换”Player
到NPC
/User
以进行特定的方法调用,否则您通常希望避免这种情况。
如果您可以将方法定义在Player
适用于所有玩家的级别,您将更容易实现和调用所需的方法。
例如
class PlayerDefinitions {
public static void main(String[] args) {
User user = new User(0);
NPC npcPlayer = new NPC(1, filterBehaviour, selectBehavior);
List<Card> nullList_or_emptyList = user.filter(...);
Card nullCard = user.select(...);
List<Card> aListOfCards = npcPlayer.filter(...);
Card aCard = npcPlayer.select(...);
}
}
interface Player {
// methods that apply to all players go here
// You can provide a no-op implementation for User if not required by User
ArrayList<Card> filter(Hand hand, Hand trick, Whist.Suit trumps);
Card select(ArrayList<Card> hand, Hand trick, Whist.Suit trumps)
}
abstract class PlayerId {
private int playerId;
public PlayerId(int playerId) {
this.playerId = playerId;
}
}
class User extends PlayerId implements Player {
public User(int playerNumber) {
super(playerNumber);
}
public void clickInteraction() {
// some code
}
@Override
public ArrayList<Card> filter(Hand hand, Hand trick, Whist.Suit trumps) {
return null;
}
@Override
public Card select(ArrayList<Card> hand, Hand trick, Whist.Suit trumps) {
return null;
}
}
class NPC extends PlayerId implements Player {
private Hand hand;
private int score;
private Actor scoreActor;
IFilterBehaviour filterBehaviour;
ISelectBehaviour selectBehaviour;
public NPC(int playerNumber, IFilterBehaviour filterBehaviour, ISelectBehaviour selectBehaviour) {
super(playerNumber);
this.filterBehaviour = filterBehaviour;
this.selectBehaviour = selectBehaviour;
this.hand = null;
}
//strategy pattern filter
@Override
public ArrayList<Card> filter(Hand hand, Hand trick, Whist.Suit trumps) {...}
//strategy pattern select
@Override
public Card select(ArrayList<Card> hand, Hand trick, Whist.Suit trumps) {...}
}
我还建议您有一个Game
类来控制轮到哪个玩家,而不是试图让所有玩家都跟踪活跃玩家是谁。这种分离将使事情变得更清晰。
推荐阅读
- arduino - 无法使用 arduino uno 的 AT 命令发送短信
- javascript - 如何在Node js中等待多个回调
- c# - 在 WPF 中创建可扩展的“应用程序分组/集线器”
- .net - 使用 SQL Server 2016 解析 XML
- vba - Microsoft Access 列表框为空,即使指定了 RowSource 并返回结果
- python-3.x - 带有 TensorFlow 的 NumPy 数据“不在同一张图上”
- mongodb - 如何处理 MongoDB/DynamoDB 中的循环文档?
- javascript - 如何将一个数组中的首字母与另一个数组中的值匹配?
- python-3.x - gtk3 帧标签位置 3.18 与 3.22
- dataframe - pyspark 数据帧同时按多列排序