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



作为一个练习,我正在编写一个程序来初始化单个虚拟纸牌,并且我还使用enum作为主类,如下所示。

问题出在这里

在下面的代码块中,我尝试将suit和rank同时输入到这个变量中,但是Intellij说输入"Jack"因为诉讼不是声明。错误信息"不是语句"(它在"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语法问题)

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

CardMaker Card = (Hearts, "Jack");

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

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

然而,当我相应地改变你的代码时,我得到以下[编译器]错误:

Cannot instantiate the type CardMaker

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

尽管如此,你的enum看起来很奇怪。为什么它包含一个类型相同的枚举成员?

我建议使用两个枚举:一个用于suit,另一个用于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;
}
}

注意,enumRank使用了一种hack使Rank的值与卡的实际值相匹配。参见Java枚举如何以1

开头最后,类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实例,因此不需要在CardMake类的构造函数中检查该参数。

您需要重写方法toString(),因为如果您不这样做,它将使用超类(这是java.lang.Object)的方法,该方法返回一个类似于以下的字符串。

CardMake@1f

我还假设您可能想要检查两张牌是否相等,因此我添加了方法equals(它也覆盖了超类方法)。如果你要重写方法equals,建议也重写方法hashCode(再次在超类中,即java.lang.Object)。

方法printf中的格式字符串不需要1$,特别是在只有一个参数的情况下。关于java.util.Formatter

类,请参阅javadoc

你不需要显式地调用toString方法,printf方法会为你做这些。

最后,还建议使用Java命名约定。

运行上述代码产生如下输出:

Here's your card: JACK of HEARTS

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

我已经重写了你的类和枚举。你应该这样做。你对枚举的理解是不正确的。你可以考虑命名常量的枚举。不能在枚举中放置数据变量和函数。


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

最新更新