Inheritance in the Wild
Note: This is a verbatim copy of a discussion post I made for IT-145 at SNHU. I liked it so I’m putting it here.
The first principle, inheritance, describes one’s ability to describe data objects in a way that can be extended to create new types while reducing repeated code. This plays well with another programming principle: the DRY principle which states, in its most simple and reduced form: Don’t Repeat Yourself (Don’t Repeat Yourself, n.d.) One of the key advantages to inheritance is that you can hold a collection of objects referenced by their parent classes. There are pitfalls in relying too heavily on inheritance. Heavily subclassed codebases are more difficult to understand, read, and most importantly, unit test. The trick is to inherit the right classes. There’s a simple way of getting a general idea if inheritance may be the right call. Does the proposed subclass describe an “is a” or a “has a” relationship? Let’s use an Animal class. A cat “is an” animal; therefore, inheritance likely makes sense to describe their relationship. However, if the relationship can be described as “has a” (a cat “has a” tail), then it’s better to describe the relationship through composition (Nero, 2020.)
The second principle, encapsulation, describes grouping like items together as a logical whole and limiting access to the internals in order to create atomic objects that aren’t affected by, and do not affect, outside classes. This is seen most commonly by class member variables and are often what is being stored when discussing the aforementioned method of composition.
The third principle, abstraction, is the idea of distilling the essence of an object to its most core component pieces and providing an interface for interacting with those pieces. At the most basic level, it can be described as the verbs that can be performed on, or by, an object. Going back to our Cat example, a cat’s abstraction not only includes its properties (color, size, etc) but also the things it can do (Walk, Run, Meow, Purr, Eat, Hunt) and the things that can be done to it (Pet, Feed, Pick Up).
Finally, the last principle of polymorphism is the idea that classes related by inheritance can implement the same interface with different implementations. Let’s assume we have a Feline parent class with a defined function of Eat. This Eat function can be implemented differently on the Cat class (eats 10lbs of food per day) than on the Tiger class (eats 100lbs of food per day.) This principle is the main enabler to the example of sharing the same container. In a simulation, you can have an array of Felines which, once per iteration, calls its Eat function. This would allow different amounts of food to leave the simulation’s ecosystem based on the type of Feline without having to write duplicate code for each breed.
The most interesting thing that I’ve played with so far in this course is the idea of generics. In the final project, I used generics to create search functions for the various animal types in order to follow the DRY principle. I had used them in the past but had never had a need for creating my own in Java.
Until next time,
Don’t Repeat Yourself. (n.d.). DevIQ. https://deviq.com/principles/dont-repeat-yourself
Nero, R. D. (2020, January 8). Inheritance versus composition: How to choose. InfoWorld. https://www.infoworld.com/article/3409071/java-challenger-7-debugging-java-inheritance.html