我想弄清楚如何在不同的类中使用枚举扩展一个共同的抽象类。
简单的例子:
卡类
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;
}
}
抽象DECK类
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();
}
类BriscolaDeck
public class CarteBriscolaDeck extends Deck {
private enum SUITS{
COPPE,
DENARE,
BASTONI,
SPADE
}
private enum VALUES{
ASSO,
DUE,
TRE,
QUATTRO,
CINQUE,
SEI,
SETTE,
FANTE,
CAVALLO,
RE
}
public CarteBriscolaDeck(){
super(VALUES,SUITS);
}
}
类PokerDeck
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);
}
}
我做的对吗?是否有可能进行优化?
提前感谢。
您不能在基类中声明enum
以被子类覆盖,因为enum
总是隐式地final
。而且,子类enum
s不能扩展任意类型,它们总是隐式地扩展java.lang.Enum
。
你能做的,是在基类中声明interface
,子类enum
将实现。但是,由于您没有在枚举中指定任何可以抽象的功能,因此这样做(目前)没有意义。另一种方法是为基类指定类型参数,子类将用它们的实际类型填充这些参数。
另一件需要修复的事情是,在Card
类中使用"suite"one_answers"value"类型而不是String
s,因为在那里使用字符串会破坏使用enum
s的全部优势。
。
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);
}
}
我觉得不合适。我不明白你为什么要在这里使用Enum。Collection也可以做同样的事情,而且对读者来说更清晰。
您可以在枚举中有一个带标志的构造函数,并将相关值传递给父方法。过滤可以使用SUIT_TYPS来完成。一个或SUIT_TYPES。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
}
可没那么容易。你在子类中声明了全新的类型;因此,没有像您希望的那样隐含的"重写"。您可以看到,基类构造函数接受两个类型为Deck的枚举。西装,…传入一个类型为Poker的enum。套装不能用
一种方法是使用泛型: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()){
...
}
,然后在子类中:
public class PokerDeck extends Deck<PokerDeck.POKERSUITES, PokerDeck.POKERVALUES> {
enum POKERSUITS { SPADES, ..
enum POKERVALUES { ...
@Override
protected List<POKERSUITS> getSuiteEnum() {
return list with POKERSUITES.values());
请注意:这是更多的"伪代码"风格;所以请原谅我的错别字。来制作扑克牌。POKERSUITS工作,内部枚举也不能是私有的。我在这里选择使用抽象方法,因为它们有助于实现开/闭原则。
所以,长话短说:是的,这可以通过使用在子类中声明的enum来实现。但是说实话;我没有看到在这里使用枚举的附加价值。你不妨这样写:abstract protected List<String> getSuiteNames();
并在每个子类中轻松实现:
return Arrays.asList("SPADES", "
In Desk constructor:
public Desk(Object[] values, Object[] suits)
在子类中:
public Subclass(){
super(values.values(), suits.values())
}