Java optional interface in class hierarchy
inheritance, interface, java, styles
Solution
If a class is not pokable, I would recommend against it implementing the `Pokeable` interface, simply because that would be confusing.
Take one of the following approaches instead.
- Create an abstract or concrete subclass of `BaseClass` that implements `Pokable`, and have all of your to-be-`Pokeable` subclasses extend it. This approach works well if `poke()`ing is achieved via the same logic in all of the implementing classes.
- Have each subclass implement `Pokeable` individually
Problem
Suppose you have a Java class hierarchy of about 30 classes, with a base class BaseClass and two main subclasses (SubclassA, SubclassB) with several subclasses each. A few of these subclasses have a certain behavior. Let's say you can "poke" them, changing their state. (This is a new requirement adding behavior to an existing hierarchy. "Poke" is meaningless to the majority of classes.) ``` interface Pokeable { void poke(); int getTimesPoked(); } public class Pokey extends SubclassB implements Pokeable { private int timesPoked = 0; public void poke() { timesPoked++; } public int getTimesPoked() { return timesPoked; } } ``` Should this be done by implementing Pokeable in only those classes that need it, and then doing the following in all code that must poke any object that's pokeable? ``` public void process(BaseClass b) { if (b instanceof Pokeable) { ((Pokeable)b).poke(); } } ``` Or should the entire hierarchy implement Pokeable for the sake of the few that really ARE Pokeable? ``` interface Pokeable { void poke(); int getTimesPoked(); boolean isReallyPokeable(); } public class BaseClass implements Pokeable { public void poke() {} public int getTimesPoked() { return 0; } public boolean isReallyPokeable() { return false;} } public class Pokey { private int timesPoked = 0; @Override public void poke() { timesPoked++; } @Override public int getTimesPoked() { return timesPoked; } @Override public boolean isReallyPokeable() { return true; } } public void process(BaseClass b) { b.poke(); } ``` Edit added: It's kind of a Double Dispatch problem. Where "poker" code does something to an object, it must call "poke()" if the object is "pokeable" but can't if not. Whether you "poke()" or not depends on whether something wants to poke and whether the object accepts being poked. I could use the Visitor pattern but that seems to make it more complicated.