Should every immutable class be final?

2019-04-09 14:22发布

I was designing a Card class to be used in a Blackjack game.

My design was to make a Card class with a getValue() that returns, for example, 11 for J, 12 for Q and 13 for K, and then extend it with a BlackjackCard class to override that method so that those cards return 10.

Then something hit me: objects of the Card class should be immutable. So I re-read Effective Java 2nd Edition to see what to do and I there I found that immutable classes need to be final, to avoid a subclass to break the immutability.

I also looked in Internet and everyone seems to agree in that point.

So should the Card class be final?

How can you break the immutability of this class, be extending it:

class Card {
  private final Rank rank;
  private final Suit suit;
  public Card(Rank rank, Suit suit) {
    this.rank = rank;
    this.suit = suit;
  }
  public Rank getRank() {
    return rank;
  }
  public Suit getSuit() {
    return suit;
  }
  public int getValue() {
    return rank.getValue();
  }
}

Thanks.

7条回答
我想做一个坏孩纸
2楼-- · 2019-04-09 15:23

You can do this:

class MyCard extends Card {

  public MyCard(Rank rank, Suit suit) {
    super(rank, suit);
  }

  @Override
  public Rank getRank() {
    // return whatever Rank you want
    return null;
  }

  @Override
  public Suit getSuit() {
    // return whatever Suit you want
    return null;
  }

  @Override
  public int getValue() {
    // return whatever value you want
    return 4711;
  }

}

The extending class does even not have to declare the same constructor as the parent class. It can have a default constructor and does not care anything about the final members of the parent class. [That statement is wrong - see the comments].

查看更多
登录 后发表回答