Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should every immutable class be final?

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.

like image 297
gaijinco Avatar asked Dec 12 '22 14:12

gaijinco


1 Answers

A subclass cannot actually modify the values of private final properties in its parent, but it could behave as though it has, which is what Effective Java warns against:

Ensure that the class can't be extended. This prevents careless or malicious subclasses from compromising the immutable behavior of the class by behaving as if the object's state has changed.

like image 97
Wayne Avatar answered Dec 28 '22 11:12

Wayne