如何将多个参数输入到枚举构造函数中?

How to input multiple parameters into an enum constructor?

作为练习,我正在制作一个初始化单个虚拟纸牌的程序,并且我还使用枚举作为主要 class,如下所示。

问题出在这边的街区

在下面的代码块中,我尝试将花色和等级都输入到这个变量中,但是 Intellij 说输入“Jack”因为花色不是语句。Error Message "not a statement"(it's under "Jack").

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

代码:

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 教程告诉我枚举构造函数是如何工作的,但是第一篇没有告诉我你不能创建枚举的对象。

第二,它没有说你不能初始化一个枚举类型的对象(请解释它是如何工作的,如果它与我的问题有关)。

(这不是一个骗局,因为它是我在 java 中为这个项目提出的同一种问题,这与 c# 不同,我忽略了其他语言,因为这是一个 java语法问题)

我重写了你的 class 和枚举。你应该这样做。 你对枚举的理解是不正确的。你可以想到命名常量的枚举。您不能将数据变量和函数放在枚举中。


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);
        }
}

这行代码(来自您问题中的图像)是无效的 Java 语法。

CardMaker Card = (Hearts, "Jack");

我假设您想创建一个 CardMaker 对象,因此您需要调用构造函数,如

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

但是,当我相应地更改您的代码时,出现以下 [编译器] 错误:

Cannot instantiate the type CardMaker

那是因为您不能创建枚举的实例。您只能声明一个类型为枚举类型的变量,并为其分配枚举值之一。这就是枚举的全部目的——确保您不会分配无效值。

尽管如此,您的枚举似乎很奇怪。为什么它包含一个类型为相同枚举的成员?

我建议使用两个枚举:一个用于花色,另一个用于排名。

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;
    }
}

请注意,enum Rank 使用一种技巧使 Rank 的值与卡片的实际值匹配。参考

最后,class CardMake 包含两个成员:一个类型为 Suit 和一个类型为 Rank。 (代码后有更多注释。)

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);
    }
}

现在,您无法创建具有无效排名的 CardMake 实例,因此无需在 class CardMake.[=39 的构造函数中检查该参数=]

您需要覆盖方法 toString(),因为如果您不这样做,它将使用来自 superclass(即 java.lang.Object)的方法,其中 returns类似于以下的字符串。

CardMake@1f

我还假设您可能想要检查两张牌是否相等,因此我添加了方法 equals(它也覆盖了 superclass 方法)。如果您要覆盖方法 equals.

,建议也覆盖方法 hashCode(同样在超级 class 中,即 java.lang.Object

方法 printf 中的格式字符串不需要 1$,尤其是在只有一个参数的情况下。请参阅 javadoc 以获得 class java.util.Formatter

您不需要显式调用方法 toString,方法 printf 会为您完成。

最后也推荐使用Java naming conventions.

运行 上面的代码产生以下输出。

Here's your card: JACK of HEARTS

请注意,如果您希望值是 Jack 而不是 JACK(例如),您可以在其中一个(或两个)枚举中覆盖方法 toString