Java 不使用静态变量

Java Not Using a Static Variable

我有方法 drawPoliticCard(),我需要在另一个 class applyBonus() 的方法中使用,我可以使用静态属性轻松完成,但问题是我应该能够 运行 同时独立地运行游戏的两个实例,因此如果使用静态,两个实例将共享同一副纸牌。这就是为什么我想知道是否有办法在不使用静态属性的情况下做到这一点。我将省略属性的 getter 和 setter 以使其更简洁。

public class PoliticCard {
    private static ArrayList<Color> politicCards;

    public void setDeck(){
        setPoliticCards(new ArrayList<Color>());
            getPoliticCards().add(Color.BLACK);
            getPoliticCards().add(Color.PURPLE);
            getPoliticCards().add(Color.BLUE);
    }
    public static void drawPoliticCard(Player player){
        player.getPoliticCards().add(getPoliticCards().get(0));
        getPoliticCards().remove(0);
    }
}

public class Bonus {
    protected int number;//The number of politic cards added in BonusPoliticCard
}

public class BonusPoliticCard extends Bonus {
    public BonusPoliticCard(int number) {
        this.number=number;
    }
    public void applyBonus(Player player){
        int i=0;
        while(i<number){
            PoliticCard.drawPoliticCard(player);
            i++;
        }
    }

}

我知道要从另一个函数调用方法,您应该创建 class 的新实例,但如果我这样做,我在测试时会得到一个 nullpointerexception

public class BonusPoliticCard extends Bonus {
    public BonusPoliticCard(int number) {
        this.number=number;
    }
    public void applyBonus(Player player){
        int i=0;
        while(i<number){
            PoliticCard politicCard = new PoliticCard();
            politicCard.drawPoliticCard(player);
            i++;
        }
    }

}

public class BonusPoliticCardTest {

    @Test
    public void testBonusPoliticCard() {//This ran fine when it was static
        Bonus bonus = new BonusPoliticCard(3);
        Player player = new Player(1);
        PoliticCard politicCard = new PoliticCard();
        politicCard.setDeck();
        bonus.applyBonus(player);
        assertNotNull(player.getPoliticCards().get(2));

    }

}

您可以在 class Bonus 的构造函数中创建 class PoliticCard 的实例。因此,您将能够同时使用它们并创建游戏的多个实例:

public class BonusPoliticCard extends Bonus {
    PoliticCard p;
    public BonusPoliticCard(int number) {
        this.number=number;
        p = new PoliticCard();
    }
    public void applyBonus(Player player){
        int i=0;
        while(i<number){
            p.drawPoliticCard(player);
            i++;
        }
    }

}

我对你的代码设计有点困惑,我有以下问题 -

  1. 根据 class - BonusPoliticCard 的名称,它应该扩展 PoliticCard class。 BonusPoliticCard extends PoliticCard 更有意义。
  2. 我们真的需要 Bonus class 来保持 BonusPoliticCard 中添加的政治卡的数量。在我看来,如果需要 Bonus class,那么我认为 PoliticCard 和 Bonus 之间应该存在 HAS-A 关系。 PoliticCard HAS-A BONUS.
  3. 我们通常应该避免使用静力学,除非确实需要它们。如果我们认为我们需要静态,那么我们真的应该在需求和设计上反复思考,然后我们才应该去静态。对于实用程序 classes,我们可以使用静态方法。 我在 here.
  4. 上找到了一篇有用的文章

所以我认为你应该重新考虑一下你的设计。我的回答仅基于提供的代码。

由于问题中没有显示Player class,所以有两种情况可以抛出NullPointerException:

(1) BonusPoliticCardTest 中创建的PoliticCard 实例与您在BonusPoliticCard 中创建的实例不同class。因此,您在 BonusPoliticCardTest 中通过 politicCard.setDeck() 设置的 politicCards arrayList 永远不会与您在 BonusPoliticCard class 中创建的 PoliticCard 实例一起使用。另请注意,PoliticCard 实例的 politicCards arrayList 是在 setDeck() 中创建和设置的。因此,在调用 bonus.applyBonus(player) 期间; politicCards arrayList 引用指向 null,因此 NullPointerException 将在 getPoliticCards().get(0) 的下一行抛出:

player.getPoliticCards().add(getPoliticCards().get(0)); // inside drawPoliticCard(Player player) method

(2) Player class 应该在其构造函数中创建 ArrayList politicCards 否则我们会在以下行中为 player.getPoliticCards().add(...) 得到 NullPointerException:

player.getPoliticCards().add(getPoliticCards().get(0)); // inside drawPoliticCard(Player player) method

这是正确的代码示例:

PoliticCard.java

public class PoliticCard {
    private ArrayList<Color> politicCards;

    /**
     * @return the politicCards
     */
    public ArrayList<Color> getPoliticCards() {
        return politicCards;
    }
    /**
     * @param politicCards the politicCards to set
     */
    public void setPoliticCards(ArrayList<Color> politicCards) {
        this.politicCards = politicCards;
    }

    public void setDeck() {
        setPoliticCards(new ArrayList<Color>());
        getPoliticCards().add(Color.BLACK);
        getPoliticCards().add(Color.PURPLE);
        getPoliticCards().add(Color.BLUE);
    }

    public void drawPoliticCard(Player player) {
        player.getPoliticCards().add(getPoliticCards().get(0));
        getPoliticCards().remove(0);
    }

}

Bonus.java:

public class Bonus {
    protected int number; //The number of politic cards added in BonusPoliticCard
}

奖金PoliticCard.java

public class BonusPoliticCard extends Bonus {
    PoliticCard politicCard;
    public BonusPoliticCard(int number, PoliticCard politicCard) {
        this.number=number;
        this.politicCard = politicCard;
    }
    public void applyBonus(Player player){
        int i=0;
        while(i<number){
            politicCard.drawPoliticCard(player);
            i++;
        }
    }
}

Player.java

public class Player {
    private ArrayList<Color> politicCards;
    int num;

    public Player(int num) {
        this.num = num;
        politicCards = new ArrayList<Color>();
    }

    /**
     * @return the politicCards
     */
    public ArrayList<Color> getPoliticCards() {
        return politicCards;
    }

    /**
     * @param politicCards the politicCards to set
     */
    public void setPoliticCards(ArrayList<Color> politicCards) {
        this.politicCards = politicCards;
    }
}

BonusPoliticCardTest.java

public class BonusPoliticCardTest {

    @Test
    public void test() {
        PoliticCard politicCard = new PoliticCard();
        politicCard.setDeck();
        Bonus bonus = new BonusPoliticCard(3, politicCard);
        Player player = new Player(1);
        ((BonusPoliticCard) bonus).applyBonus(player);
        assertNotNull(player.getPoliticCards().get(2));
    }

}