我想动态地将其超类类型的变量声明为子类,但我不确定如何声明。
该程序是一个有用户和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
的方法,但很明显,当过滤器是NPC方法时,我不能使用nextlayer.filter。我能做这样的事吗?
if (playersArray(random.nextInt(nbPlayers)) instance of npc) {
nextPlayer be treated as npc
}
else { nextPlayer be treated as user }
如果您想在两种类型的播放器上调用相同的方法,请将Player
声明为interface
以及您希望子类实现的任何方法。。。如果你想让每种类型的播放器都有一个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
类,它可以控制轮到哪个玩家,而不是试图让所有玩家都知道谁是现役玩家。这种分离会让事情变得更清楚。
是的,您可以使用强制转换。像这样的
Player nextPlayer = playersArray(random.nextInt(nbPlayers)) ;
if(nextPlayer instanceof NPC) {
NPC npc= (NPC) nextPlayer;
.....[do something with npc]
}
else {
.....[Do something with nextPlayer]
}
也许不那么优雅,但它应该工作