2

New to programming, new to java. I seem to understand the basic pieces like classes and their components, methods, etc, but I can't figure out how to put them together. For example, I'm following the tutorials and trying to write a class Card that can become any card based on args passed during construction.

My first problem is, if I declare class Card public (line 5), the compiler says illegal start of expression.

If I remove public, it continues to the println statement, where it complains non-static variable can't be referenced from a static environment. That is because I'm working inside the main method, which is always static, right? So, I need to add methods to Card that will read the internal state and give it to the println statement, would that work?

public class Deck {
    public static void main(String[] args) {

    class Card {
        public int rank;
        public int suit;

        public Card(int startSuit, int startRank) {
            rank = startRank;
            suit = startSuit;
        }
    }

        Card aceOfSpades = new Card(1, 1);
        System.out.println("Card is ..." + Card.rank + " of " + Card.suit);
    }
}

Round Two Here is the new code, the file is Card.java:

public class Card {

        //declare states
        //rank 1-13 for ace-king
        //suit 1-4 spade,heart,club,diamond
        public int rank;
        public int suit;

        //constructor
        public Card(int startSuit, int startRank) {
            rank = startRank;
            suit = startSuit;

        }

        //methods for Card




        public static void main(String[] args) {
            //call Card constructor
            //make card ace of spades (1,1)
            Card aceOfSpades = new Card(1,1);

            //read internal state of new Card object
            //what kind of card is it?
            System.out.println("Card is ..." + rank + " of " + suit);
        }
}

I balanced my braces, main method is now part of Card class, I think its looking better. The oney compile errors are now associated with the variables in the println statement. (non-static variable suit can't be referenced from a static context.) I think this means I have to write methods like getSuit() and getRank() that will read the variable states and then use the method in my println and not the variables themselves?

That method would look like this, right?

public int getSuit() {

    return suit;

}

(pls bear with me, my formatting isn't coming out exactly correct, I'll work on it)

nexus_2006
  • 744
  • 2
  • 14
  • 29
  • 1
    Create a new file called `Card.java` and put your `Card` class in there. – Sotirios Delimanolis Apr 20 '13 at 17:53
  • Or create it directly in the Deck class (not in a method!!). – ddmps Apr 20 '13 at 17:54
  • OK, I figured it out. I was making a Card, but not using it. I should have been referencing aceOfSpades.rank, not Card.rank. For object-oriented programming it helps to actually make/use an object. Future googlers - I did end up putting the getSuit() and getRank() methods inside card, just above the main method. – nexus_2006 Apr 20 '13 at 18:57
  • The same thing error non-static access. – Roman C Apr 20 '13 at 19:08

3 Answers3

0

The names of your classes have to match the name of their files.

However, from Bill K's answer to can I compile a java file with a different name than the class:

You CAN have secondary classes inside the same file as long as they are not public. They can still be "default" though, so they can still be used by other classes in the same package.

This should not be done for the most part. Java's naming patterns regarding classes and packages are one of the bigger advantages it has--makes a programmers life easier at no cost.

Community
  • 1
  • 1
0x6C38
  • 6,796
  • 4
  • 35
  • 47
  • Simplistically, yes, but ultimately untrue for a variety of reasons. In *this* case it's what I'd recommend, but not because it's the only way to declare classes. – Dave Newton Apr 20 '13 at 17:58
  • So the invalid expression was public, if I had called the inner class Card private, it would have worked? – nexus_2006 Apr 20 '13 at 18:29
  • @nexus_2006 No, it can't have access modifiers. And why it doesn't make life more easier. – Roman C Apr 20 '13 at 18:51
  • Oh, ok. Got it. I reread the section on inner classes, makes more sense now. – nexus_2006 Apr 20 '13 at 18:56
0

Move class Card out of the body of method main(). All of this code should be in a file having the same name as the outer class, Deck.java.

David R Tribble
  • 11,918
  • 5
  • 42
  • 52
  • The file name was Deck.java, but now I have remove class Deck, called the entire thing Card.java, with just a Card class. Thanks – nexus_2006 Apr 20 '13 at 18:28
0

Your second code is nearly correct. You just have to modify the code in main like this :

 System.out.println("Card is ..." + aceOfSpades.rank + " of " + aceOfSpades.suit);

You are right about the static, main is static he can access only variables that are static. By adding aceOfSpades you specify the object you have created. You have a reference and you can read the internal values rank and suit.

But as you suggest a better way is to create setter/getter methods : setRank(int), getRank(), .... You can replace

public int rank;
by 
private int rank; 

So your internal values are protected outside the object.
Note that even if you set your rank as private, the main() method can still read directly the value of rank. It is because private means only visible in the class and main is part of your class.
But if you instanciate a Card object in you Deck object, it will not be able to read directly the content.

The idea of hiding the internal values of the objects is fundamental in OO and is called encapsulation

mki
  • 635
  • 3
  • 10