求助:如何将单类代码拆分为Card、Deck、DeckOfCards三类并使用ArrayList?
Hey there! Let's break this down step by step—splitting your code into three classes makes total sense for separation of concerns, and using ArrayList will make managing your cards way more flexible than fixed-size arrays. Let's walk through each class's purpose, how they collaborate, and write some example code to tie it all together.
1. The Card Class
This is your smallest, most focused class—it should only handle the properties and behavior of a single playing card. Think of it as a blueprint for what a card is and what it can do.
public class Card { // Private fields to encapsulate card details (encapsulation is key!) private final String suit; private final String rank; // Constructor to create a new Card instance public Card(String suit, String rank) { this.suit = suit; this.rank = rank; } // Getters to access the card's suit/rank (since fields are private) public String getSuit() { return suit; } public String getRank() { return rank; } // Override toString to print the card nicely (e.g., "Ace of Spades") @Override public String toString() { return rank + " of " + suit; } }
- Why this works: By keeping
Cardfocused on individual card data, you avoid cluttering other classes with details about suits/ranks. Other classes only need to use theCardobject, not worry about how it's structured internally.
2. The Deck Class
This class manages a collection of Card objects—its job is to build a full deck, shuffle it, and handle operations like dealing cards. We'll use ArrayList<Card> here because it dynamically resizes (no more manual array merging!) and has built-in methods to make managing the deck easier.
import java.util.ArrayList; import java.util.Collections; public class Deck { private ArrayList<Card> cards; // Constructor builds a full 52-card deck public Deck() { cards = new ArrayList<>(); // Define all suits and ranks String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"}; String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"}; // Loop through suits and ranks to create every possible Card for (String suit : suits) { for (String rank : ranks) { cards.add(new Card(suit, rank)); } } } // Shuffle the deck using Collections.shuffle() public void shuffle() { Collections.shuffle(cards); } // Getter to access the deck's cards (or add a method to deal a single card!) public ArrayList<Card> getCards() { return cards; } // Optional: Method to deal one card from the top of the deck public Card dealCard() { if (!cards.isEmpty()) { return cards.remove(0); } return null; // Or throw an exception if deck is empty } }
- Cross-class call here: When we do
new Card(suit, rank), we're calling theCardclass's constructor to create a new card instance. TheDeckdepends onCardto exist, but it doesn't need to know howCardworks—just that it can create one with a suit and rank.
3. The DeckOfCards Class (Your Main Driver)
This class acts as the entry point for your program—it will create a Deck instance, call its methods (like shuffle), and handle output. It's the glue that brings the other two classes together.
public class DeckOfCards { public static void main(String[] args) { // Create a new deck (this triggers the Deck constructor, which builds all 52 cards) Deck myDeck = new Deck(); // Shuffle the deck myDeck.shuffle(); // Print all cards in the shuffled deck System.out.println("Shuffled Deck:"); for (Card card : myDeck.getCards()) { System.out.println(card); } // Example: Deal the first 5 cards System.out.println("\nDealt Cards:"); for (int i = 0; i < 5; i++) { Card dealtCard = myDeck.dealCard(); if (dealtCard != null) { System.out.println(dealtCard); } } } }
- How collaboration works here:
DeckOfCardscreates aDeckobject.- It calls
myDeck.shuffle()—this tells theDeckclass to handle the shuffling logic internally. - It uses
myDeck.getCards()to access the list ofCardobjects, then loops through them and calls eachCard'stoString()method to print the card.
Key Takeaways for Multi-Class Collaboration
- Single Responsibility Principle: Each class does one thing:
Cardhandles individual card data,Deckmanages the collection of cards,DeckOfCardsruns the program. - Encapsulation: Keep fields private (like
Card's suit/rank) and use getters to access them—this prevents other classes from messing with internal data directly. - Dependency: Classes depend on each other, but only through public methods.
Deckdoesn't need to know howDeckOfCardsuses it, and vice versa.
内容的提问来源于stack exchange,提问作者Velislav Rumenov

