如何从静态方法轻松访问各种类实例中的变量

时间:2014-01-06 18:46:59

标签: java static

我一直在制作纸牌游戏 Gin Rummy 的基本模拟,虽然目前还不完整,但它能够运行一副纸牌的基本功能,直到我试过实现一种方法来处理每个玩家的手。

班级Player应该由ArrayList(每个玩家手中持有牌)和integer(用作玩家ID)组成。我已将这些对象声明为static,但当然这意味着我创建的每个Player实例都具有相同的Handplayerid,因为变量是静态的。

这是我当时面临的问题。我始终相信任何static类或方法,只能访问其他static类,方法对象等。因为main方法必须是static,所以它肯定是任何东西可以访问也必须static等等等等?我的Player类中的对象如何不是静态的,因此允许我为Player的每个实例分配不同的Handplayerid

我已将我的代码包含在下面,我很抱歉它已经很久了,我以为我会把所有东西放进去以防万一。对于记录,它是PlayGinRummy类中的一些点,我将Player的新实例称为抛出错误non-static variable Hand cannot be referenced from a static context

package labexercise1;

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class DeckOfCardsTest {

public DeckOfCardsTest(){}

private static int Menu;

public static void main(String[] args) throws InterruptedException{

    DeckOfCards.FillDeck(); 

    do{
        Thread.sleep(1000);
        System.out.println("Please select from the following menu options using the corresponding number:");
        System.out.println("1. Display Deck | 2. Shuffle Deck | 3. Cut Deck | 4. Start Game | 5. Exit"); //Start game will lead into another switch menu to set no of players etc.
        System.out.print("Your choice: ");
        Scanner UserInput = new Scanner(System.in);
        System.out.println();
        Menu = UserInput.nextInt(); // Maybe build in a system that recognises, for example, "1", "one" and "One" as the menu selection 1, using if/else
        System.out.println();

        switch(Menu){
            case 1:
                DeckOfCards.DisplayDeck();
                break;

            case 2:
                DeckOfCards.ShuffleDeck();
                break;

            case 3:
                DeckOfCards.CutDeck();
                break;

            case 4:
                PlayGinRummy.DealDeck(); // Maybe shuffle things around so this just calls a method in player, from which everything else is called. Would mean moving things over from DeckOfCards so Player had access to hp, cp1, cp2 and cp3.
                break;

            case 5: 
                System.out.println("The program will now end.");
                System.out.println();
                break;

            default: 
                System.out.println("Your input is not a valid selection.");
                System.out.println();
                break;
        }
    } while(Menu!=5);
}

public class DeckOfCards {

    public DeckOfCards(){}

    public static ArrayList<Integer> Deck = new ArrayList<>(); 
    public static ArrayList<Integer> Discard = new ArrayList<>();

    public static void FillDeck() throws InterruptedException{
        System.out.print("Compiling deck");
        DeckOfCards.CountdownEffect();
        for(int count=0; count<52; count++){
            Deck.add(count);
        }
        System.out.println(" Deck compiled!");
        System.out.println();
    }   

    public static void DisplayDeck() throws InterruptedException{
        System.out.println("Displaying deck contents:");
        Thread.sleep(1000);
        for(int count=0; count<52; count++){
            System.out.println(Deck.get(count));
        }
        System.out.println();
    }

    public static void ShuffleDeck() throws InterruptedException{
        System.out.print("Shuffling deck");
        Thread.sleep(1000);
        for(int count=0; count<3; count++){
            System.out.print(".");
            Thread.sleep(1000);
        }
        Collections.shuffle(Deck);
        System.out.println(" Deck shuffled!");
        System.out.println();
    }

    public static void CutDeck() throws InterruptedException{
        System.out.print("Cutting deck");
        Thread.sleep(1000);
        for(int count=0; count<3; count++){
            System.out.print(".");
            Thread.sleep(1000);
        }
        System.out.println();
        System.out.println("The cut card is:");
        Random random = new Random();
        int CutPoint = 51 - (random.nextInt(52));
        System.out.println(Deck.get(CutPoint));
        System.out.println();
    }

    public static void CountdownEffect() throws InterruptedException{
        Thread.sleep(1000);
        for(int count=0; count<3; count++){
            System.out.print(".");
            Thread.sleep(1000);
        }
    }
} 

public class Player{

    public Player(ArrayList<Integer> h, int id, int n){
        Hand = new ArrayList<>(h);
        playerid = id;
        NoOfPlayers = n;
    }

    public ArrayList<Integer> Hand;
    public int playerid;
    public static int NoOfPlayers;

    public int SizeOfHand(){
        int s = Hand.size();
        return s;
    }

    public void DisplayHand() throws InterruptedException{
        System.out.print("Displaying ");
        if (playerid==1)
            System.out.print("player's");
        else if (playerid==2)
            System.out.print("computer player 1's");
        else if (playerid==3)
            System.out.print("computer player 2's");
        else if (playerid==4)
            System.out.print("computer player 3's");
        System.out.println(" hand:");
        Thread.sleep(1000);
        for(int count=0; count<7; count++){
            if (count<6)
                System.out.print(Hand.get(count) + ", ");
            else if (count==6)
                System.out.println(Hand.get(count) + ".");
        }
    }
}

public class PlayGinRummy {

    public PlayGinRummy(){}

    public static int NoOfPlayers;

    public static void DealDeck() throws InterruptedException{
        int cardno, playerno; // Tracks index of top card
        System.out.println("Please input the desired number of players (2-4): ");
        Scanner UserInput = new Scanner(System.in);
        NoOfPlayers = UserInput.nextInt(); 
        System.out.println();
        System.out.println();

        cardno=51;
        playerno=0;

        do{
            if (NoOfPlayers==2){
                Player hp = new Player(Player.Hand,1,NoOfPlayers); 
                Player cp1 = new Player(Player.Hand,2,NoOfPlayers);

                do{
                    if (playerno%2==0)
                        hp.Hand.add(DeckOfCards.Deck.get(cardno));
                    else if (playerno%2==1)
                        cp1.Hand.add(DeckOfCards.Deck.get(cardno));

                    DeckOfCards.Deck.remove(cardno);

                    playerno++;
                    cardno--;
                }while(hp.SizeOfHand()!=7 && cp1.SizeOfHand()!=7);

                hp.DisplayHand();
                cp1.DisplayHand();
            }
            else if (NoOfPlayers==3){
                Player hp = new Player(Player.Hand,1,NoOfPlayers);
                Player cp1 = new Player(Player.Hand,2,NoOfPlayers);
                Player cp2 = new Player(Player.Hand,3,NoOfPlayers);

                do{
                    if (playerno%3==0)
                        hp.Hand.add(DeckOfCards.Deck.get(cardno));
                    else if (playerno%3==1)
                        cp1.Hand.add(DeckOfCards.Deck.get(cardno));
                    else if (playerno%3==2)
                        cp2.Hand.add(DeckOfCards.Deck.get(cardno));

                    DeckOfCards.Deck.remove(cardno);

                    playerno++;
                    cardno--;
                }while(hp.SizeOfHand()!=7 && cp1.SizeOfHand()!=7 && cp2.SizeOfHand()!=7);

                hp.DisplayHand();
                cp1.DisplayHand();
                cp2.DisplayHand();
            }
            else if (NoOfPlayers==4){
                Player hp = new Player(Player.Hand,1,NoOfPlayers);
                Player cp1 = new Player(Player.Hand,2,NoOfPlayers);
                Player cp2 = new Player(Player.Hand,3,NoOfPlayers);
                Player cp3 = new Player(Player.Hand,4,NoOfPlayers);

                do{
                    if (playerno%4==0)
                        hp.Hand.add(DeckOfCards.Deck.get(cardno));
                    else if (playerno%4==1)
                        cp1.Hand.add(DeckOfCards.Deck.get(cardno));
                    else if (playerno%4==2)
                        cp2.Hand.add(DeckOfCards.Deck.get(cardno));
                    else if (playerno%4==3)
                        cp3.Hand.add(DeckOfCards.Deck.get(cardno));

                    DeckOfCards.Deck.remove(cardno);

                    playerno++;
                    cardno--;
                }while(hp.SizeOfHand()!=7 && cp1.SizeOfHand()!=7 && cp2.SizeOfHand()!=7 && cp3.SizeOfHand()!=7);

                hp.DisplayHand();
                cp1.DisplayHand();
                cp2.DisplayHand();
                cp3.DisplayHand();
            }
            else{
                System.out.println("The choice made is invalid, please try again.");
                System.out.println();
            }
        }while(NoOfPlayers!=2 && NoOfPlayers!=3 && NoOfPlayers!=4);       

        System.out.println();
    }
}    

1 个答案:

答案 0 :(得分:2)

  

由于“main”方法必须是静态的,当然它可以访问的任何东西也必须是静态的等等吗?

没有。静态方法可以访问实例方法。他们通过使用实例来实现这一目标。 main创建实例以使用实例方法(类main本身或其他类中的任何一种)非常非常常见。

总的来说:

public static final void main(String[] args) {
    SomeClass instance = new SomeClass();
    instance.method();
}

如果你正在创造一些小而且完全独立的东西,main创建它所在的类是很常见的。例如:

public class Simple {
    private String name;

    public static final void main(String[] args) {
        // Create a couple of instances
        Simple s1 = new Simple();
        Simple s2 = new Simple();

        // Use instance methods
        s1.setName("s1");
        s2.setName("s2");
        System.out.println(s1.getName());
        System.out.println(s2.getName());
    }

    private void setName(String name) {
        this.name = name;
    }

    private String getName() {
        return this.name;
    }
}

在那里,我使用了两个独立的实例来强调。我为它们使用了单独的变量,但当然如果您要将它们视为分组列表或实例集,您可能使用数组ListSet。数组示例:

public class Simple {
    private String name;

    public static final void main(String[] args) {
        // Create the array (no instances are created)
        Simple[] simples = new Simple[2];

        // Create a couple of instances, set their names
        for (int n = 0; n < simples.length; ++n) {
            simples[n] = new Simple();
            simples[n].setName("s[" + n + "]");
        }

        // Use instance methods
        for (Simple s : simples) {
            System.out.println(s.getName());
        }
    }

    private void setName(String name) {
        this.name = name;
    }

    private String getName() {
        return this.name;
    }
}