4
\$\begingroup\$

From what I've read, I should use abstract classes when I want to define behavior for a superclass, and I don't want to instantiate the superclass. So, I'm making a Blackjack game in Java, and I want a BlackjackDealer class and a BlackjackPlayer class. Would it be okay to make these children of a BlackjackPerson class, since some of the behavior should be the same? An example of behavior that should be the same:

abstract class BlackjackPerson {

   protected Card[] cards;
   public void hit(Card c) {
       // add c to cards
   }

   public abstract void displayHand();
   // print out hand
}

An example of a BlackjackDealer class, with its own implementation of the displayHand method (since a dealer has 1 card hidden):

class BlackjackDealer extends BlackjackPerson {
    public void displayHand() {

        for (Card c : cards) {
            System.out.println(c);
        }
    }
}

This is my first time using inheritance, I just want to know if I'm on the right track.

\$\endgroup\$

closed as off-topic by Ludisposed, mdfst13, Zeta, Toby Speight, Mast Jan 22 at 14:18

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Ludisposed, mdfst13, Zeta, Toby Speight, Mast
If this question can be reworded to fit the rules in the help center, please edit the question.

2
\$\begingroup\$

Look for common functionality

The real power of inheritance comes from the existence of common functionality. In this case, the dealing of cards and the calculation of totals will be common to both players and dealers, and so having both of these in the parent class would be a good choice.

Look for differing functionality

A dealer will have rules on when they hit and when they stay. A player will likely have an amount bet and a chip balance. These would be candidates for inclusion in the child classes.

\$\endgroup\$
1
\$\begingroup\$

Congratulations on taking class inheritance with a pinch of salt. This is a tricky part of OOP due to the strong dependency created between the parent and child classes and yet out of an urge for classification many people apply it badly, myself included.

As I understand, you have Blackjack players and one of them is the Dealer. So I would have this simple specialization: BlackjackDealer extends BlackjackPlayer. None of them would be abstract, so sorry if you wanted to put abstract classes to use.

You employ abstract classes when you want to provide partial functionality in a class but it seems that you don't have any to belong to the parent class. This is why I recommend the previous simpler design.

\$\endgroup\$
  • \$\begingroup\$ I do see what you mean about just regular inheritance, but aren't there some behaviors that the player needs that the dealer cannot have (like betting per Joe C's example). \$\endgroup\$ – robert Jan 21 at 22:05
  • \$\begingroup\$ Having a BlackjackPerson class doesn't make much sense to me. At least in the naming it should be renamed to BlackjackPlayer. Everyone involved are playing a game anyway. Of course, if you have special functionality to a Dealer subclass and some other special to a Player subclass then go ahead and create the abstract class. I'm not familiar with the game so I cannot proceed further. One other thing, don't forget you can have interface inheritance. \$\endgroup\$ – Piovezan Jan 21 at 22:12
1
\$\begingroup\$

When using inheritance, always answer the 'Sub is a Super?'

Would it be okay to make these children of a BlackjackPerson class, since some of the behavior should be the same?

or

Look for common functionality

This is a thing that often goes wrong. Just because there is a bit of similar behavior does not necessarily mean there is a 'is-a' relation.

For example, both a Human and a Car can moveForward(). Does this mean a Human is a Car or a Car is a Human. Surely not :)

Let's think about the common behaviour of a BlackJackPlayer and a BlackJackDealer. It is displayHand(). Can a BlackJackDealer be seen as a BlackJackPlayer? I would say yes, it is a special kind of player which have some specialized behavior. So I think, in your case, it would be fine to have

BlackJackDealer extends BlackJackPlayer 

No need for abstract supertypes.

\$\endgroup\$
  • \$\begingroup\$ I see your point, this is similar to what Piovezan said. However, what do I do about behavior specific to the player? For instance, a player can split, bet, etc. If I make the dealer inherit player, then the dealer will be able to bet, which it should not be. \$\endgroup\$ – robert Jan 22 at 17:03
  • \$\begingroup\$ Well, then it becomes different :) The player and dealer obviously have some similarity; like displayHand(). But there is no real supertype (as in, there does not exist a 'blackjackperson' who is neither a player or dealer, so we need an AbstractBlackjackPlayer, which can never be instantiated. \$\endgroup\$ – RobAu Jan 23 at 7:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.