This is one of those cases where it makes sense to subclass a non-abstract class.
class Mammal { ... void walk() { ... do some walking ... } } class WateronlyMammal extends Mammal { @Override void walk() { ... sit there looking sad ... } }
Then create animal types like new Mammal("Dog") or new WateronlyMammal("Dolphin") .
An alternative you may need is a composition instead of inheritance that trades verbosity for simpler components.
interface Walker { void walk(); } final class Mammal { public Mammal(String speciesName, Walker walk) { ... } ... }
Creation as new Mammal("Dog", competentWalker()) or new Mammal("Dolphin", notSoGoodWalker()) .
May even add convenience constructors:
public Mammal(String speciesName) { this(speciesName, competentWalker(), poorFlyer()); }
(Note that we have some confusion here with the type of species and the particular animal. It is also worth noting that if you take every animal that has ever existed, there are no species boundaries.)
source share