In step
暂无分享,去创建一个
ion Be clear about your abstraction; a class should do one thing well. It’s tempting to add a lot of support functions when you’re designing a reusable class. Yet every method, property, and event that you add to the interface limits your choices in implementation, making it more difficult for the class to do one job well. A clear abstraction is easier for developers to use correctly because the properties and methods make sense and the behavior is predictable. Interface Provide a complete interface but don’t go overboard. Implement the interface well enough so that the next developer can extend it. For example, the Hand class you implement in this chapter has a method to remove pairs. You could also add a method to remove runs of cards—for example, the Jack, Queen, and King of Hearts. However, you could instead create a new class, based on the Hand class. Because the Hand class exposes all the cards through an indexer and provides a Remove method, you can implement the method to remove the run of cards in the new extended class. Client code Well-designed classes streamline the client code. Much of the looping and decision structures are contained in the class methods rather than in the client code. The method calls are marked by an absence of arguments because the class encapsulates the information needed to execute the method. In this chapter, you’ll create a Deck class that has a parameterless constructor to create the standard 52-card deck. The Deck class will have a deal method that takes an array of Hand instances to which to deal the cards. Dealing cards to two hands is straightforward and even reads like a problem: get a deck, shuffle it, find a couple of players, and deal the cards to the players. ‘ Visual Basic Dim aDeck As New Deck() aDeck.Shuffle() hand1 = New Hand() hand2 = New Hand() aDeck.Deal(New Hand() {hand1, hand2}) // Visual C# Deck aDeck = new Deck(); aDeck.Shuffle(); hand1 = new Hand(); hand2 = new Hand(); aDeck.Deal(new Hand[] {hand1, hand2}); Creating the Card Class The first class to implement is the Card class, because the Hand and Deck classes can’t exist without the Card class. You’ll run into fewer compilation errors by implementing the Card class first. Create the class 1. Create a new project and name it DeckOfCards . 2. On the Project menu, click Add Class. The Add New Item dialog box appears. 3. Name the file Card.vb or Card.cs, depending on the language you’re using. The suit and value of the card will be based on enumerations. Create the enumerations 1. Add the following code for the Suit enumeration. If you’re using Visual Basic, add the code to Card.vb before the Card class block. This enumeration is declared outside the Card class. If you’re using Visual C#, add this code before the Card class block and within the DeckOfCards namespace block. If you define the Suit enumeration within the Card class, the Suit property will collide with the Suit enumeration. 2. ‘ Visual Basic 3. Public Enum Suit 4. Hearts 5. Diamonds 6. Clubs 7. Spades 8. End Enum 9. 10. // Visual C# 11. public enum Suit { 12. Hearts, 13. Diamonds, 14. Spades, 15. Clubs, } 16. Add the following code after the Suit enumeration for the FaceValue enumeration: 17. ‘ Visual Basic 18. Public Enum FaceValue 19. Ace 20. One 21. Two 22. Three 23. Four 24. Five 25. Six 26. Seven 27. Eight 28. Nine 29. Ten 30. Jack 31. Queen 32. King 33. End Enum 34. 35. // Visual C# 36. public enum FaceValue { 37. Ace, Two, Three, Four, Five, Six, Seven, 38. Eight, Nine, Ten, Jack, Queen, King } Create the fields and properties 1. Add the following code for the Suit property: 2. ‘ Visual Basic 3. Private m_suit As Suit 4. Public Property Suit() As Suit 5. Get 6. Return m_suit 7. End Get 8. Set(ByVal Value As Suit) 9. m_suit = Value 10. End Set 11. End Property 12. 13. // Visual C# 14. private Suit m_suit; 15. public Suit Suit { 16. get { return m_suit; } 17. set { m_suit = value; } } 18. Add the following code for the FaceValue property: 19. ‘ Visual Basic 20. Private m_faceValue As FaceValue 21. Public Property FaceValue() As FaceValue 22. Get 23. Return m_faceValue 24. End Get 25. Set(ByVal Value As FaceValue) 26. m_faceValue = Value 27. End Set 28. End Property 29. 30. // Visual C# 31. private FaceValue m_faceValue; 32. public FaceValue FaceValue { 33. get { return m_faceValue; } 34. set { m_faceValue = value; } } Create the constructor § Add the following code for the constructor: § ‘ Visual Basic § Public Sub New(ByVal newSuit As Suit, ByVal newValue As Face Value) § m_suit = newSuit § m_faceValue = newValue § End Sub § § // Visual C# § public Card(Suit newSuit, FaceValue newValue) { § m_suit = newSuit; § m_faceValue = newValue; § } That completes the Card class. The Card class itself isn’t terribly interesting, but what you can do with a group of cards is. You can work with a whole deck, shuffling, sorting, and dealing. You can also work with a small collection of cards (a hand), adding and removing cards and finding and removing pairs. Creating the Hand Class Because the Deck class uses the Hand class, you’ll create the Hand class next. That way, you’ll won’t run into compilation errors by using the Hand class before it’s been defined. Create the class and constructors 1. On the Project menu, click Add Class. The Add New Item dialog box appears. 2. Name the file Hand.vb or Hand.cs, depending on the language you’re using. 3. Add the following constructors for the Hand class. A new hand could start out without cards or with an array of cards. The cards are contained in an ArrayList object. (The parameterless constructor for C# is created with the source file.) 4. ‘ Visual Basic 5. Private m_cards As New System.Collections.ArrayList() 6. 7. Public Sub New() 8. End Sub 9. 10. Public Sub New(ByVal cards() As Card) 11. m_cards.AddRange(cards) 12. End Sub 13. 14. // Visual C# 15. private System.Collections.ArrayList m_cards = 16. new System.Collections.ArrayList(); 17. public Hand() { 18. } 19. 20. public Hand(Card[] cards) { 21. m_cards.AddRange(cards); } Create the fields and properties 1. Add the following code to return the count of the cards in the hand. The value must be passed out of the class through a property because m_cards is a private member of the Hand class. 2. ‘ Visual Basic 3. Public ReadOnly Property Count() As Integer 4. Get 5. Return m_cards.Count 6. End Get 7. End Property 8. 9. // Visual C# 10. public int Count { 11. get { return m_cards.Count; } } 12. Add the following code to create a default property or indexer for the class: 13. ‘ Visual Basic 14. Default Public ReadOnly Property Cards(ByVal indexer As Intege r) As Card