Java 抽象类中的枚举
我试图弄清楚如何在扩展公共抽象类的不同类中使用enum 简单的例子:Java 抽象类中的枚举,java,enums,abstract,Java,Enums,Abstract,我试图弄清楚如何在扩展公共抽象类的不同类中使用enum 简单的例子: 卡片类 public class Card { private String name; private String value; private String suit; public Card(String name, String value, String suit) { this.value = value; this.suit= suit;
卡片类
public class Card {
private String name;
private String value;
private String suit;
public Card(String name, String value, String suit) {
this.value = value;
this.suit= suit;
}
}
抽象甲板类
public abstract class Deck {
private enum SUITS{
}
private enum VALUES{
}
private int cardNumber;
private ArrayList<Card> cardList;
public Deck(VALUES valori,SUITS semi){
ArrayList<Card> clist = new ArrayList<>();
for (SUITS s: semi.values()){
for (VALUES v: valori.values()){
cardList.add(new Card(v.toString(),s.toString()));
}
}
cardNumber = cardList.size();
}
类扑克牌
public class PokerDeck extends Deck {
private enum SUITS{
SPADES,
HEARTS,
DIAMONDS,
CLUBS
}
private enum VALUES{
ACE,
TWO,
THRRE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING
}
public PokerDeck(){
super(VALUES,SUITS);
}
}
我做得对吗?有可能优化吗
提前谢谢你。没那么容易。您正在子类中声明全新的类型;因此,没有你所希望的隐含的“覆盖”。 你看,你的基类构造函数需要两个Deck.suites类型的枚举。。。因此,传入Poker.SUITS类型的枚举无法工作 一种解决方法是使用泛型:
abstract class Deck<S extends Enum<S>, V extends Enum<V>> {
abstract protected List<S> getSuiteEnums();
abstract protected List<V> getValuesEnums();
public Deck(){
ArrayList<Card> clist = new ArrayList<>();
for (S s: getSuiteEnums()){
...
}
我认为它不合适。我不明白你为什么要在这里使用Enum。 收藏可以做同样的事情,让读者更清楚。在桌面构造器中:
public Desk(Object[] values, Object[] suits)
在子类中:
public Subclass(){
super(values.values(), suits.values())
}
在枚举中可以有一个带标志的构造函数,并将相关值传递给super方法。可以使用西服类型1或西服类型2进行过滤
public enum SUITS {
COPPE(SUIT_TYPES.ONE.name()),
DENARE(SUIT_TYPES.ONE.name()),
BASTONI(SUIT_TYPES.ONE.name()),
SPADE(SUIT_TYPES.ONE.name()),
SPADES(SUIT_TYPES.TWO.name()),
HEARTS(SUIT_TYPES.TWO.name()),
DIAMONDS(SUIT_TYPES.TWO.name()),
CLUBS(SUIT_TYPES.TWO.name());
private final String type;
SUITS(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
enum SUIT_TYPES {
ONE, TWO
}
不能在基类中声明要由子类重写的
enum
,因为enum
s总是隐式地final
。此外,子类“enum
s”不能扩展任意类型,它们总是隐式扩展java.lang.enum
您可以做的是在基类中声明一个接口
,子类“enum
将实现该接口。但是,由于您没有在枚举中指定任何可以抽象的功能,所以(目前)这样做没有意义。另一种方法是为基类指定类型参数,子类将用它们的实际类型填充基类
另一个需要解决的问题是,在Card
类中使用“suite”和“value”类型而不是String
s,因为在那里使用String会破坏使用enum
s的全部优势
例如
公共期末成绩卡{
终审法院的诉讼;
最终V值;
公共卡(S套装,V值){
这套衣服;
这个值=值;
}
@凌驾
公共字符串toString(){
返回值+“”+值;
}
}
公务舱甲板{
受保护的最终套装;
保护最终设定值;
受保护的最终清单所有卡片;
公共甲板(类suitType、类valueType){
Set suits=EnumSet.allOf(suitType);
Set values=EnumSet.allOf(valueType);
List cardList=newarraylist(suits.size()*values.size());
适用于(S套房:套装){
对于(V值:值){
卡片列表。添加(新卡(套件、价值));
}
}
allSuits=集合。不可修改集合(suits);
allValues=Collections.unmodifiableSet(值);
allCards=集合。不可修改列表(cardList);
}
@凌驾
公共字符串toString(){
返回getClass().getSimpleName()+所有卡片;
}
}
公共类扑克牌扩展牌组{
enum套装{黑桃、红桃、钻石、梅花}
枚举值{ACE,2,3,4,5,6,7,
八,九,十,杰克,皇后,国王}
公共扑克牌组(){
super(Suits.class、Values.class);
}
}
公共类卡特尔公司
延伸甲板{
enum套装{COPPE、DENARE、BASTONI、SPADE}
枚举值{ASSO、DUE、TRE、QUATTRO、CINQUE、SEI、SETTE、FANTE、CAVALLO、RE}
公共卡特尔公司{
super(Suits.class、Values.class);
}
}
我认为您可能不熟悉枚举的概念,或者您的回答不清楚如何使用数组而不是枚举,在这种情况下,您应该改进它。您没有看到枚举在表示少量预定义值方面的优势吗?比较更快,类型检查更严格。OP的真正问题是,卡
字段是字符串,而不是那些枚举的实例。可能需要再坐20分钟才能找到一个基于枚举的解决方案,允许在这里使用它们;也适用于子类化的事情。但老实说:我已经在这里呆了很长时间;没有任何“回报”。。。所以,不确定这是否会很快发生。提示:请让我知道我的答案是否适合你;或者如果你还想找别的东西;否则,请考虑接受最佳的答案,以表示“你得到了你所需要的”。你写道:保护最后一套所有的西装;保护最终设定值;和after allSuits=Collections.unmodifiableSet(suits);allValues=Collections.unmodifiableSet(值);是打字错误吗?因为final意味着一个costant。。对吗?final
字段在构建后不能修改。但是,当然,他们必须在施工期间分配一次。在这里,它发生在构造函数的末尾,在集合被填充之后。检查IDE中的代码是否与此处发布的代码完全相同,以及必须添加的必要的import
语句。此代码经过测试,在构造函数中分配最终
字段的能力至关重要。重要的是,它必须在构造函数中,并且必须是一次(每个可能的代码路径)。字段本身不能有初始值设定项。
return Arrays.asList("SPADES", "
public Desk(Object[] values, Object[] suits)
public Subclass(){
super(values.values(), suits.values())
}
public enum SUITS {
COPPE(SUIT_TYPES.ONE.name()),
DENARE(SUIT_TYPES.ONE.name()),
BASTONI(SUIT_TYPES.ONE.name()),
SPADE(SUIT_TYPES.ONE.name()),
SPADES(SUIT_TYPES.TWO.name()),
HEARTS(SUIT_TYPES.TWO.name()),
DIAMONDS(SUIT_TYPES.TWO.name()),
CLUBS(SUIT_TYPES.TWO.name());
private final String type;
SUITS(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
enum SUIT_TYPES {
ONE, TWO
}
public final class Card<S,V> {
final S suit;
final V value;
public Card(S suit, V value) {
this.suit = suit;
this.value = value;
}
@Override
public String toString() {
return suit+" "+value;
}
}
public class Deck<S extends Enum<S>,V extends Enum<V>> {
protected final Set<S> allSuits;
protected final Set<V> allValues;
protected final List<Card<S,V>> allCards;
public Deck(Class<S> suitType, Class<V> valueType) {
Set<S> suits =EnumSet.allOf(suitType);
Set<V> values=EnumSet.allOf(valueType);
List<Card<S,V>> cardList=new ArrayList<>(suits.size()*values.size());
for(S suite: suits){
for(V value: values) {
cardList.add(new Card<>(suite, value));
}
}
allSuits =Collections.unmodifiableSet(suits);
allValues=Collections.unmodifiableSet(values);
allCards =Collections.unmodifiableList(cardList);
}
@Override
public String toString() {
return getClass().getSimpleName()+allCards;
}
}
public class PokerDeck extends Deck<PokerDeck.Suits,PokerDeck.Values> {
enum Suits { SPADES, HEARTS, DIAMONDS, CLUBS }
enum Values { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING }
public PokerDeck(){
super(Suits.class, Values.class);
}
}
public class CarteBriscolaDeck
extends Deck<CarteBriscolaDeck.Suits,CarteBriscolaDeck.Values> {
enum Suits { COPPE, DENARE, BASTONI, SPADE }
enum Values { ASSO, DUE, TRE, QUATTRO, CINQUE, SEI, SETTE, FANTE, CAVALLO, RE }
public CarteBriscolaDeck(){
super(Suits.class, Values.class);
}
}