This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Beginning Java and the fly likes Encapsulation seems to make inheritance counter productive in this example? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Encapsulation seems to make inheritance counter productive in this example?" Watch "Encapsulation seems to make inheritance counter productive in this example?" New topic
Author

Encapsulation seems to make inheritance counter productive in this example?

Faz Ali
Greenhorn

Joined: Dec 02, 2010
Posts: 21
I am creating a base class called Deck which will hold cards and will consist of an ArrayList instance variable. Obviously this variable will be private for encapsulation reasons but then how will any class extending the Deck class be able to make changes to methods such as addCard(), removeCard() without access to the ArrayList?
The only thing I can think of is an accessor method to the ArrayList but then that exposes the entire implementation of the class and really makes encapsulation go down the toilet no? - It's the same as making the ArrayList public

The reason I mention this is because I am making a set of interfaces and classes for a card game which will consist of the following:


Some guidance on the best approach will be appreciated, thanks.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3615
    
  14

Well, why do you need a base class (I'm assuming it's Cardholder?) and what functionality are your other classes going to add to it? It's not very clear from your example.

Can you explain what CardHolder does that wouldn't be available in a List<PlayingCard>?
Faz Ali
Greenhorn

Joined: Dec 02, 2010
Posts: 21
Stephan van Hulst wrote:Well, why do you need a base class (I'm assuming it's Cardholder?) and what functionality are your other classes going to add to it? It's not very clear from your example.

Can you explain what CardHolder does that wouldn't be available in a List<PlayingCard>?


It's best if I explain the problem with the classes I have written (without any use of interfaces, abstract classes, inheritance etc)

First, I have a regular deck which is instantiated with 52 standard deck, adds cards to the end of the deck, deals cards from the top of the deck, can be shuffled and lastly returns its size:



Next up we have a shreddedDeck which is very similar to a PlayingDeck with some slight variations. It adds cards to the beginning of the list and removes from the end of the list. The exact opposite of the PlayingDeck. Also, it cannot be shuffled. It shares several method names with PlayingDeck but only has the same implementation for getSize(). Also it has an extra method which returns the faceCard without removing it from the deck:



Lastly I have a hand class which is also similar to the PlayingDeck and ShreddedDeck classes but with slight variations and the addition of methods for sorting and adding cards in certain indices. It has an addCard() and getSize() method which are exactly the same as the PlayingDeck implementations but all other methods are unique:



Looking at these 3 classes, there have some shared method names and some shared implementations. The are also unique methods between the classes but in essense, they are all 'Card Holders'. My aim is to design these classes with OO in mind. I must admit, I am only beginning thinking of OO so any guidance as to what I can do with these 3 classes is appreciated.
By the way, very sorry for the very long post but I thought actual code would better illustrate my dilemma.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3615
    
  14

Well, the Deque interface really already specifies most of this behaviour. You could just use the LinkedList class, which implements both the List and the Deque interfaces.
What you could do is define a static method in your Card class that returns a LinkedList<Card> containing the standard 52 cards.

If you're really looking to get the exercise, you can declare your CardHolder class to implement java.util.List<Card> and java.util.Deque<Card>, and implement all the methods yourself. You can also extend AbstractList<Card> to get you started.

This way, you will only have one class (CardHolder), and let the card games that use CardHolders (for instance, as decks, discard piles or hands) be responsible for using them correctly.
Faz Ali
Greenhorn

Joined: Dec 02, 2010
Posts: 21
Stephan van Hulst wrote:Well, the Deque interface really already specifies most of this behaviour. You could just use the LinkedList class, which implements both the List and the Deque interfaces.
What you could do is define a static method in your Card class that returns a LinkedList<Card> containing the standard 52 cards.

If you're really looking to get the exercise, you can declare your CardHolder class to implement java.util.List<Card> and java.util.Deque<Card>, and implement all the methods yourself. You can also extend AbstractList<Card> to get you started.

This way, you will only have one class (CardHolder), and let the card games that use CardHolders (for instance, as decks, discard piles or hands) be responsible for using them correctly.


Thanks for the input Stephan. I have taken it on board and what I've come up with is below. Essentially it is a wrapper around a linkedList collection which implements all the methods a 'card list' minimally needs to have. The card games which use them will be responsible for implementing them and this class can therefore be used as a deck, discard pile, hand etc. Please let me know if this is what you meant:

Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3615
    
  14

Well, I don't really want to be a party pooper, but my point is that CardList really doesn't add anything that LinkedList doesn't already have. The only difference is that you check for null elements, and you don't allow duplicates. The former is good, but you shouldn't restrict duplicates from being added to your class (some card games, like Canasta, shuffle two or even three standard decks together).

So really, all that your class does is check for null elements. Your design would be a lot cleaner if you just dropped the class completely, and let specific card games keep track of their own LinkedList<Card>, and make them responsible for not adding any null elements to it.

Here's an example of what I mean. Here, the game is responsible for maintaining all the cards:
Faz Ali
Greenhorn

Joined: Dec 02, 2010
Posts: 21
Stephan van Hulst wrote:Well, I don't really want to be a party pooper, but my point is that CardList really doesn't add anything that LinkedList doesn't already have. The only difference is that you check for null elements, and you don't allow duplicates. The former is good, but you shouldn't restrict duplicates from being added to your class (some card games, like Canasta, shuffle two or even three standard decks together).

So really, all that your class does is check for null elements. Your design would be a lot cleaner if you just dropped the class completely, and let specific card games keep track of their own LinkedList<Card>, and make them responsible for not adding any null elements to it.

Here's an example of what I mean. Here, the game is responsible for maintaining all the cards:


To be honest with you, when I was creating that class, I was wondering the same thing; I'm not really doing anything thats not already in the LinkedList class and it just feels wrong. What you've highlighted makes perfect sense and I'm already making the changes. Sometimes OO really gets to me because I find it hard when to decide if I need to create a class myself or if I should use an already existing class which should have a limited interface than one offered by another class. - Such is the case with this example whereby a deck in my game will not use every method implemented by linkedlist but therefore I ask myself if I usually ask myself should I still use it.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3615
    
  14

Well, creating new classes is about making life easier for yourself. Facades have their place, but in this case it's just extra work. People are familiar enough with the Collection classes that they don't need an extra wrapper.
Limiting an interface can be good, but it's not very necessary, since LinkedList has a fairly clear API.

Getting a feel for when you create new classes and when you reuse old ones, that's a matter of experience.
 
 
subject: Encapsulation seems to make inheritance counter productive in this example?