如何基于抽象类Card向ArrayList添加对象以创建牌组
问题描述
我正尝试将Card对象添加到Card类型的ArrayList中以创建一副牌组。为此遍历了牌的花色和数值,尝试添加Card对象时,出现无法实例化Card类型的错误。
Card类代码
public abstract class Card { public static final String FACES[] = {"ZERO","ACE","TWO","THREE","FOUR", "FIVE","SIX","SEVEN","EIGHT","NINE","TEN","JACK","QUEEN","KING"}; private String suit; private int number; //constructors public Card(){ } public Card ( int num, String type) { number = num; suit = type; } // modifiers //accessors public String getSuit() { return suit; } public int getNumber() { return number; } public abstract int getValue(); public boolean equals(Object obj) { if (getNumber()==((Card) obj).getNumber()) { return true; } return false; } //toString public String toString () { int var = getNumber(); return FACES[var] + " of " + getSuit() + " | Value " + getValue(); }
Deck类代码
import java.util.ArrayList; import java.util.Collections; public class Deck { public static final int NUMFACES = 13; public static final int NUMSUITS = 4; public static final int NUMCARDS = 52; public static final String SUITS[] = {"CLUBS","SPADES","DIAMONDS","HEARTS"}; private int topCardIndex; private ArrayList<Card> stackOfCards; public Deck () { //initialize data - stackOfCards - topCardIndex topCardIndex = 0; for (int i=0;i<NUMSUITS;i++){ for( int j=0; j<NUMFACES; j++) { stackOfCards.add(new Card(j,SUITS[i])); } }//loop through suits //loop through faces //add in a new card } //modifiers public void shuffle () { //shuffle the deck //reset variables as needed } //accessors public int size () { return 0; } public int numCardsLeft() { return stackOfCards.size(); } public Card nextCard() { return stackOfCards.get(topCardIndex--); } public String toString() { return stackOfCards + " topCardIndex = " + topCardIndex; } }
问题原因与解决方法
核心问题
错误根源是Card被定义为抽象类,Java中抽象类不能通过new关键字直接实例化——抽象类包含未实现的抽象方法(比如getValue()),它的设计目的是作为父类被继承,而非直接创建对象。
解决步骤
创建Card的具体子类,实现抽象方法
getValue()
以标准扑克牌为例,创建StandardCard类:public class StandardCard extends Card { public StandardCard(int num, String type) { super(num, type); } @Override public int getValue() { // 按扑克牌规则实现点数:J/Q/K返回10,其余返回自身数值 int num = getNumber(); return num >= 10 ? 10 : num; } }修改Deck类的实例化代码
将Deck构造方法中的new Card(j,SUITS[i])替换为子类对象,同时补充stackOfCards的初始化(否则会触发空指针异常):public Deck () { topCardIndex = 0; stackOfCards = new ArrayList<>(); // 初始化ArrayList for (int i=0;i<NUMSUITS;i++){ for( int j=0; j<NUMFACES; j++) { stackOfCards.add(new StandardCard(j,SUITS[i])); } } }可选方案
如果不需要抽象类的设计特性,也可以直接移除Card类的abstract修饰符,并实现getValue()方法,这样就能直接实例化Card对象,但会丢失抽象类强制子类规范实现的优势。
内容的提问来源于stack exchange,提问作者mishifishy
相关产品推荐
相关产品推荐

