在简单的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))

我想能够使用NPCUser的方法,但很明显,当过滤器是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。这是多余的,可以删除。

除非您需要";下铸";对于要进行的特定方法调用的PlayerNPC/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] 
}

也许不那么优雅,但它应该工作

最新更新