首页 > 解决方案 > 在简单的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显然我不能使用 nextPlayer.filter 当 filter 是 NPC 方法时。我可以做这样的事情吗?

if (playersArray(random.nextInt(nbPlayers)) instance of npc) {
        nextPlayer be treated as npc
} 
else { nextPlayer be treated as user }

标签: javainheritance

解决方案


如果您想在两种类型的播放器上调用相同的方法,请声明Player为 aninterface以及您希望子类实现的任何方法...如果您希望每种类型的播放器都有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类来控制轮到哪个玩家,而不是试图让所有玩家都跟踪活跃玩家是谁。这种分离将使事情变得更清晰。


推荐阅读