Reputation: 151056
Just as an example, if House
is the base class, and Colonial
is a subclass of House
, and Colonial has a method that is goUpstairs
. There is another class called Mansion
which is also a subclass of House
, and Mansion
has a method useElevator
(say a mansion can have many floors, such as 1 to 35).
Should things start out this way? Or what if after 6 months, there need to be a new class Duplex
which is a subclass of House
, and also requires a method goUpstairs
? If we duplicate the goUpstairs
code in Colonial
and Duplex
, then it is not so DRY (Don't Repeat Yourself). Should the classes be designed different initially? Or should be it designed differently only after the 6 months and how should it be changed?
Upvotes: 1
Views: 196
Reputation: 43243
Well in a case like this, let's think a bit about the semantics.
So, thinking like this, we will naturally arrive at composition.
Rather than put the methods for going up in the house itself, think of the house as a container for components. A mansion could exist without an elevator too.
So, you implement an Elevator
class and a Stairs
class (or maybe Escalator
). If they share some code, or methods such as goUp
or goDown
, you could have some interface or base class like IVerticalTransport
or whatever.
Continuing with this train of thought, you would also have a Floor
object. An IVerticalTransport
would connect one or more Floor
s, which in turn would be contained in a House
.
Expanding this slightly to again include the Mansion and Duplex concepts you mentioned, it would probably make sense to have a HouseFactory
. A HouseFactory
would have methods to configure House
s with specific settings.
HouseFactory.getMansion()
would return a House
with 4 Floor
s and several Stair
sHouseFactory.getDuplex()
would return a House
with 10 Floor
s and two Elevator
sI could go on and on with this really... :D
Upvotes: 0
Reputation: 9606
I don't think it is a good idea to build such an inheritance tree. As you stated it come to a permutational explosion
Try using "interfaces"
In java
public abstract class House {
...
}
public interface HasStairs {
public boolean putUpstairs (Thing x);
public boolean putDownstairs (Thing x);
}
public interface HasElevator {
public boolean putUp (Thing x);
public boolean putDown (Thing x);
public boolean putTo (Thing x, Floor pFloor);
}
public MyHouseA extends House {}
public MyHouseB extends House implements HasStairs {}
public MyHouseC extends House implements HasElevator {}
public MyHouseD extends House implements HasStairs, HasElevator {}
Upvotes: 2
Reputation: 5706
if the house is a complete (Not Abstract) class then it should only have the functionality common in ALL of it's subclasses. If you want to have multiple classes have similar functions that aren't common to all the houses you could have multiple subclasses.
Public House ...
Public MultiLevelHouse extends House {
public void goUpstairs() ...
Public Duplex extends MultiLevelHouse {
...
Public Colonial extends MutliLevelHouse {
...
Public Mansion extends MutliLevelHouse {
//Override goUpstairs to use useEvalator if you want
...
Upvotes: 1