Home > database >  How to input multiple parameters into an enum constructor?
How to input multiple parameters into an enum constructor?

Time:09-27

For an exercise I'm making a program that initializes a single virtual playing card, and I'm also using an enum as the main class as shown below.

The problem is this block over here

In the below code block I try to input both suit and rank into this variable, but Intellij says inputting "Jack" as the suit isn't a statement.Error Message "not a statement"(it's under "Jack").

 public static void main(String[] args)
    {
        CardMaker Card = (Hearts, "Jack");
        Card.printCard();
    }

Code:

import java.util.Arrays;
public enum CardMaker
{
    Hearts, Spades, Clubs, Diamond;
    CardMaker Suit;
    String[] Ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
    String Rank = "";
    CardMaker(CardMaker Suit, String Rank)
    {
        this.Rank = Rank;
        this.Suit = Suit;
        if(Arrays.binarySearch(Ranks, Rank) < 0)
        {
            System.out.println("Invalid Rank try again");
            System.exit(1);
        }
    }
    private String[] Card = {String.valueOf(Suit), Rank};

    CardMaker()//This stops a error I forgot which one
    {

    }

    private String printCard()
    {
        System.out.printf("Here's your card '%1$s" ,Card.toString());
        return Card.toString();
    }

    public static void main(String[] args)
    {
        CardMaker Card = (Hearts, "Jack");
        Card.printCard();
    }


}

https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html The tutorial told me how enum constructors work, but 1st didn't tell me that you can't make an object of an enum.

2nd it didn't say that you couldn't initialize a object of an enum type(Please explain how that works and if it relates to my issue).

(This isn't a dupe as while it's the same kind of question I'm asking it for this project in java which is different then c# I ignored other languages as this is a java syntax question)

CodePudding user response:

This line of code (from the image in your question) is not valid Java syntax.

CardMaker Card = (Hearts, "Jack");

I assume you want to create a CardMaker object, hence you need to call the constructor, as in

CardMaker Card = new CardMaker(Hearts, "Jack");

However, when I change your code accordingly, I get the following [compiler] error:

Cannot instantiate the type CardMaker

That is because you cannot create an instance of an enum. You can only declare a variable whose type is the enum type and assign it one of the enum values. That is the whole purpose of an enum – to ensure that you don't assign an invalid value.

Nonetheless, your enum seems strange. Why does it contain a member whose type is the same enum?

I suggest using two enums: one for suit and another for rank.

public enum Suit {
    CLUBS, DIAMONDS, HEARTS, SPADES;
}

public enum Rank {
    TWO,
    THREE,
    FOUR,
    FIVE,
    SIX,
    SEVEN,
    EIGHT,
    NINE,
    TEN,
    JACK,
    QUEEN,
    KING,
    ACE;

    public int getValue() {
        return ordinal()   2;
    }
}

Note that enum Rank uses a kind of hack to make the value of the Rank match the actual value of the card. Refer to How can a Java enum start with 1

Finally, class CardMake contains two members: one whose type is Suit and one whose type is Rank. (More notes after the code.)

public class CardMake {
    private Rank rank;
    private Suit suit;

    public CardMake(Suit suit, Rank rank) {
        this.rank = rank;
        this.suit = suit;
    }

    public boolean equals(Object obj) {
        boolean areEqual = false;
        if (obj instanceof CardMake) {
            CardMake other = (CardMake) obj;
            areEqual = suit.ordinal() == other.suit.ordinal()  &&  rank.ordinal() == other.rank.ordinal();
        }
        return areEqual;
    }

    public int hashCode() {
        return suit.ordinal() * 10   rank.getValue();
    }

    public String toString() {
        return String.format("%s of %s", rank, suit);
    }

    public static void main(String[] args) {
        CardMake card = new CardMake(Suit.HEARTS, Rank.JACK);
        System.out.printf("Here's your card: %s%n" ,card);
    }
}

Now, you can't create an instance of CardMake with an invalid rank, so no need to check that parameter in the constructor of class CardMake.

You need to override method toString() because if you don't, it uses the method from the superclass (which is java.lang.Object) which returns a string similar to the following.

CardMake@1f

I also assume that you may want to check whether two cards are equal, hence I added method equals (which also overrides the superclass method). And it is recommended to also override method hashCode (again in the superclass, i.e. java.lang.Object) if you are overriding method equals.

The format string, in method printf, does not need the 1$, especially not if there is only one argument. Refer to the javadoc for class java.util.Formatter

You don't need to explicitly call method toString, method printf does that for you.

Finally, it is also recommended to use Java naming conventions.

Running the above code produces the following output.

Here's your card: JACK of HEARTS

Note that you can override method toString in either (or both) enums if you want the value to be Jack rather than JACK (for example).

CodePudding user response:

I have rewritten your class and enum. You should do it this way. And your understanding of the enum is incorrect. As you can think enum of named constants. You can't put data variables and functions inside the enum.


enum Suit {
        Hearts,
        Spades,
        Clubs,
        Diamond
}

enum Rank {
        ONE,
        TWO,
        THREE,
        FOUR,
        FIVE,
        SIX,
        SEVEN,
        EIGHT,
        NINE,
        TEN,
        Jack,
        Queen,
        King,
        Ace
}

class CardMaker {
        Suit name;
        Rank rank;

        public CardMaker(final String cardName, final String cardRank) {
                this.name = Suit.valueOf(cardName);
                this.rank = Rank.valueOf(cardRank);
        }

        @Override
        public String toString() {
                return "Name : "   name   " rank : "   rank;
        }
}

class Scratch {
        public static void main(String[] args) {
                CardMaker card = new CardMaker(Suit.Hearts.name(), Rank.ONE.name());
                System.out.println(card);
        }
}
  • Related