Take a look at the StiffTerminator#destroy(Terminator) method. You can tell there is a need for
different ways to destroy a terminator. Yet at the same time you don't want to duplicate the rest of
the code. Thus the first thing that comes to mind is to inherit.
ShakyTerminator extends StiffTerminator adding a Shotgun as a field therefore making Punch not
only obsolete but also irrelevant. Yet due to the nature of inheritance it is required that you
specify its value. You can choose to pass in null. However you do have to make sure null is a valid
value by the StiffTerminator design which may well affect any of your subclasses. Else you have to
introduce it as an argument to your ShakyTerminator constructor,
introducing extra and unnecessary complexity.
In addition you need to elevate the access modifier of the StiffTerminator from private to protected.
You start sacrificing encapsulation. Not only you've made all those sacrifices but your code
starts to looks messy.
The truth is that you don't have to create a new Terminator class! If you look closely you'll see
that you need to somehow make the Punch#punch(Terminator)polymorphic. That is definitely one
way to look at it. In that case you need to introduce an interface
and have your Punch implement it
as well as any other classes.
Though this will work in some cases it's not always possible (3rd party classes), not in context or
there are a couple classes involved. The fact of the matter is it's more about composition and
less of polymorphism.
Now, you still need to introduce an interface but your classes don't need to directly implement it.
Rather you introduce a new class - implementing that interface - for each composition. Anonymous
classes can be of great use in this case.
What you end up with allows you to have more readable, flexible and high reusable code instead.
Identify the method(s) that are subject to change in your class
Introduce a new interface with all the identified methods
Add a new field of that type in your class and as an argument to the constructor
Delegate each call to your interface method respectively
Create one class for every implementation using composition to encapsulate the dependencies
Kudos to Gihub for making a truly amazing social code repository
Starting with this post, the complete source code will be available in github for every post I make under a Creative Commons Licence with an attribution that requires a link back to the qnoid. Will also try and add the source code for all my previous posts. Hope this will give you better understanding and allow you to experiment further