2016-02-13 2 views
0

У меня проблема с наследованием.Палуба карт, проблема с наследованием?

В основном я пытаюсь научить себя объектно-ориентированному программированию, и я не могу заставить свой массив перечислений использовать метод toString, который я создал для него. Вместо этого он использует один из класса PlayingCards.

Как исправить это?

public class PlayingCards { 

private final Rank rank; 
private final Suit suit; 

/** 
* Creates enums for rank 
*/ 
public static enum Rank { 

    ACE(1), 
    TWO(2), 
    THREE(3), 
    FOUR(4), 
    FIVE(5), 
    SIX(6), 
    SEVEN(7), 
    EIGHT(8), 
    NINE(9), 
    TEN(10), 
    JACK(11), 
    QUEEN(12), 
    KING(13); 
    private int rank; 

    private Rank(int rank) { 
     this.rank = rank; 
    } 

    public int getRank() { 
     return this.rank; 
    } 

} 

/** 
* Creates enums for suit 
*/ 
public static enum Suit { 

    HEARTS(14), 
    SPADES(15), 
    CLUBS(16), 
    DIAMONDS(17); 
    private int suit; 

    private Suit(int suit) { 
     this.suit = suit; 
    } 

    public int getSuit() { 
     return suit; 
    } 

} 

/** 
* Constructs a card with specified initial rank and suit 
* 
* @param rank sets rank to ACE by default 
* @param suit sets suit to SPADES by default 
*/ 
public PlayingCards(Rank rank, Suit suit) { 
    this.rank = rank; 
    this.suit = suit; 
} 

public String toString() { 
    return getClass().getName() + "[Rank = " + this.rank 
      + ", Suit = " + this.suit + "]" + "\n"; 
} 

public String format() { 
    return this.rank + " of " + this.suit; 
} 

/** 
* Tests whether this card is equal to some other card. 
* 
* @param otherObject the card to be tested. 
* @param rank imports enums rank 
* @param suit imports enums suit 
* @return returns true if the suit and rank of test card is equal to the 
* suit and rank of this card otherwise false is returned. 
*/ 
public boolean equals(Object otherObject, Rank rank, Suit suit) { 
    if (otherObject == null) { 
     return false; 
    } 
    if (getClass() != otherObject.getClass()) { 
     return false; 
    } 
    PlayingCards other = (PlayingCards) otherObject; 
    return suit == other.suit && rank == other.rank; 
} 

} 

В этом разделе есть проблемы. Он создает массив отлично, но он просто отображает его в компиляторе с использованием метода toString из неправильного класса.

import java.util.Arrays; 

public class Pack extends PlayingCards 
{ 
static PlayingCards[] card = new PlayingCards[52]; 
PlayingCards.Suit[] suit2 = PlayingCards.Suit.values(); 
PlayingCards.Rank[] rank2 = PlayingCards.Rank.values(); 
private int numberOfCards; 
/** 
* Constructs a pack of 52 cards. 
* Sorted by suit Clubs, Diamonds, Hearts, Spades. 
* Sorted ascending. 
* @param rank 
* @param suit 
*/ 
public Pack(Rank rank, Suit suit) 
{ 
super(rank,suit); 
    card = new PlayingCards[52]; 
    numberOfCards = 0; 
    for (int x = 0; x < suit2.length; x++) 
    { 
     for (int y = 0; y < rank2.length;y++) 
     { 

      card [numberOfCards] = new PlayingCards(rank2[y],suit2[x]); 
      numberOfCards ++; 
     } 
    } 
} 

/** 
* Shuffles cards in pack. 
*/ 
public void shuffle() 
{ 
} 

/** 
* @return string representation of 52 card pack. 
*/ 

@Override 
public String toString() { 
String toString = "New pack\n"; 
    for (int cards =0; cards < card.length; cards++) 
    { 
     toString = toString + card[cards] + "\n"; 
    } 
    return toString; 
} 
} 

Это то, что я получаю. В результате отформатирован неправильный toString метода:

assed3.PlayingCards[Rank = ACE, Suit = HEARTS] 
, assed3.PlayingCards[Rank = TWO, Suit = HEARTS] 
, assed3.PlayingCards[Rank = THREE, Suit = HEARTS] 
, assed3.PlayingCards[Rank = FOUR, Suit = HEARTS] 
, assed3.PlayingCards[Rank = FIVE, Suit = HEARTS] 
+1

Вы можете разбить свой код, чтобы отделить раздел, где вы столкнулись с проблемами (и добавить то, что вы ожидаете) от остальной части определения класса (возможно, удалить общий ненужный код) –

ответ

1

я не могу получить мое перечисление массива использовать метод ToString

Вы должны точно сказать, что происходит. Обычно такого рода ошибки могут быть диагностированы с помощью отладчика, но одна проблема у вас есть

for (int cards =0; cards <=card.length; cards++) 

, который должен быть

for (int cards =0; cards < card.length; cards++) 

и если это так, то вы бы получить ошибку, показывая, что в проблема в том, какая именно строка имеет ошибку.

2

Проблемы/ошибки в коде:

  • именовании. Класс PlayingCards должен быть переименован в PlayingCard. Экземпляр этого класса будет представлять один игральная карта, не многие. Вы хотите назвать свои классы именами, которые представляют объекты, которые они моделируют в реальном мире. Это позволяет избежать путаницы при программировании с этими классами и делает код более интуитивным.

  • Is-a relationship between superclass and subclass. Колода карт не игральная карта. Вы ошибаетесь, чтобы класс Deck наследовал от класса PlayingCard, это не имеет никакого смысла. Колода карт состоит из игральных карт. В этом случае отмените соотношение наследования между Deck и PlayingCard.

Если вы примените эти два, ваша проблема, скорее всего, будет решена уже.


Других замечания:

  • Равные методы должны быть переопределены из Object.equals.Метод equals, который у вас есть сейчас в классе PlayingCards, не имеет никакого смысла. Самый простой способ реализовать переопределение - попросить вашу среду IDE создать для вас реализацию. Например, когда вы работаете в Eclipse, вы можете попросить его сгенерировать его для вас. Почти во всех случаях предусмотренная реализация будет в порядке.

  • Если у вас есть overriden equals, вы должны вообще (читать: всегда) также переопределять Object.hashCode: равные объекты должны иметь одинаковые хэш-коды. Обычно вы также можете попросить свою IDE предоставить вам реализацию.

  • Когда вы переопределяете метод из суперкласса, всегда добавляйте аннотацию @Override к методу. Это будет ясно сигнализировать о том, что метод является переопределением. Это может быть не очень важно для переопределения Object.toString, потому что каждый знает этот метод, но в других классах для разных методов он значительно упрощает обзор кода. Метод с аннотацией @Overrideявляется, безусловно, переопределением. Метод без этой аннотации может быть или не быть, в зависимости от суперкласса. Метод, который не переопределяет метод в суперклассе с аннотацией @Override, приведет к ошибке компилятора. Чем яснее, тем лучше.

  • Наличие костюма, представленного целым числом, является глупым. Предложите костюм, представленный String: «Сердца», «Клубы», «Диаманс», «Пики».

  • Имея PlayingCards.Suit[] suit2 и PlayingCards.Rank[] rank2 в качестве членов класса Deck, является пустой тратой памяти. Если вы хотите присвоить ряды или костюмы своему участнику PlayingCards[] card, используйте PlayingCards.Suit.values() и PlayingCards.Rank.values() непосредственно в вашем конструкторе.

  • int numberOfCards - переменная-член, которую вы используете в конструкторе как переменная цикла. Вы не должны объявлять это как член, но должны объявлять его как локальную переменную в своем конструкторе. Это не означает, что у вас нет члена, представляющего общее количество карт в колоде, но вы не должны использовать его как переменную цикла.

  • Вы добавляете \n к строкам для новых строк, но некоторые операционные системы ожидают \r\n для разделителей строк. Вы можете получить правильный разделитель строк для операционной системы, с которой вы работаете, используя System.getProperty("line.separator").

  • Строки здания лучше всего использовать с использованием класса StringBuilder. Способ построения строки в toString, представляющий колоду, создает новую String на каждой итерации. Этот способ работы потребляет много памяти и разбивает кучу, приводящую к фрагментации.

  • В вашей установке класса теперь, с Deck вытекающего из PlayingCards вы неправильно предполагая, что когда PlayingCards.toString вызывается из Deck.toString реализации, что getClass().getName() возвращает имя класса для класса Deck. По крайней мере, я думаю, что вы ожидаете. Поскольку вы звоните PlayingCards.toString на экземпляр PlayingCards, getClass().getName() вернет PlayingCards, добавленный именем пакета.

+0

Спасибо за совет, я предварительно полученным изменения, которые вы предложили, но у меня все еще есть ошибка. –

+0

@ RyanWard Это потому, что ваше понимание вопроса неверно. См. Последнюю пулю. Результат правильный, ваше ожидание неверно. Обратите внимание, что вам крайне редко приходится относиться к именам классов, что определенно не в этом случае. –

Смежные вопросы