It’s so fluffy I’m gonna die!!!

Introduction

In the second article of the pillars of object oriented programming article series

I am going to talk about inheritance.

Imagine a happy little cat family. We have two parent cats, a white daddy cat who runs really fast and a black mommy cat who jumps really high, and a whole bunch of cute little kittens. Let’s have a look at one of their children. In an object oriented world this tiny little ball of furr would be black and white and capable of running really fast and jumping really high. Now, before someone with a biological background throws a genetics book at my face, please let us stay in an object oriented world.

Inheritance describes a parent-child relationship between two classes. One class, referred to as the subclass, inherits variables and methods from another class, referred as the superclass. The child class and the parent class are in a so called “IS-A” relationship.

The main purpose of inheritance is to avoid code duplication and thus leads to code-reusability, better maintainability and best of it all, DRY code.

The Problem with this problem

We are now going to write a User.class that uses our Preferences.class to save and load preferences. But we have to differentiate between three different users.

  • User – Is able to load the preferences, but is not allowed to change, hence save them
  • Maintainer – Maintains a List of Users and can load and also save the preferences
  • Administrator – Has a List of all Users, Maintainers and other Administrators. And can also laod and save the preferences.

Lets get the party started:

[pastacode lang=”java” manual=”public%20class%20User%20%7B%20%0A%09%0Aprivate%20String%20username%3B%20%0Aprivate%20String%20password%3B%20%0Aprivate%20String%20emailAddress%3B%20%0Aprivate%20Preferences%20preferences%3B%20%0A%0Apublic%20void%20getPreference(String%20key)%20%7B%20%0A%09Object%20pref%20%3D%20preferences.getPreference(key%2C%20null)%3B%0A%09if%20(pref%20%3D%3D%20null)%20%7B%20%0A%09%09throw%20new%20NoSuchElementException(%22No%20preference%20found%20for%20key%20’%22%20%2B%20key%20%2B%20%22’%22)%3B%20%7D%0A%09%7D%20%0A%09%0A%09%2F%2FRest%20of%20code%0A%7D” message=”User class” highlight=”” provider=”manual”/]

[pastacode lang=”java” manual=”public%20class%20Maintainer%20%7B%0A%09%0A%09private%20String%20username%3B%20%0A%09private%20String%20password%3B%20%0A%09private%20String%20emailAddress%3B%20%0A%09private%20Preferences%20preferences%3B%20%0A%09private%20Map%3CString%2C%20User%3E%20usersToMaintain%20%3D%20new%20HashMap%3CString%2C%20User%3E()%3B%20%0A%09%0A%09public%20void%20getPreference(String%20key)%20%7B%20%0A%09%09Object%20pref%20%3D%20preferences.getPreference(key%2C%20null)%3B%20%0A%09%09%0A%09%09%20if%20(pref%20%3D%3D%20null)%20%7B%0A%09%09%20throw%20new%20NoSuchElementException(%22No%20preference%20found%20for%20key%20’%22%20%2B%20key%20%2B%20%22’%22)%3B%0A%09%20%09%7D%20%0A%09%7D%20%0A%09%0A%09public%20void%20setPreference(String%20key%2C%20Object%20value)%20%7B%20%0A%09%09preferences.setPreference(key%2C%20value)%3B%20%0A%09%7D%20%0A%09%0A%09%2F%2FRest%20of%20code%0A%7D” message=”Maintainer class” highlight=”” provider=”manual”/]

[pastacode lang=”java” manual=”public%20class%20Administrator%20%7B%0A%09%0A%09private%20String%20username%3B%20%0A%09private%20String%20password%3B%20%0A%09private%20String%20emailAddress%3B%0A%09private%20Preferences%20preferences%3B%0A%09private%20Map%3CString%2C%20User%3E%20users%20%3D%20new%20HashMap%3CString%2C%20User%3E()%3B%0A%09private%20Map%3CString%2C%20Maintainer%3E%20maintainers%20%3D%20new%20HashMap%3CString%2C%20Maintainer%3E()%3B%0A%09private%20Map%3CString%2C%20Administrator%3E%20administrators%20%3D%20new%20HashMap%3CString%2C%20Administrator%3E()%3B%0A%09%0A%09%0A%09public%20void%20getPreference(String%20key)%20%7B%0A%09%09Object%20pref%20%3D%20preferences.getPreference(key%2C%20null)%3B%20%0A%09%09%0A%09%09if%20(pref%20%3D%3D%20null)%20%7B%20%0A%09%09%09throw%20new%20NoSuchElementException(%22No%20preference%20found%20for%20key%20’%22%20%2B%20key%20%2B%20%22’%22)%3B%0A%09%09%7D%0A%09%7D%0A%09%0A%09public%20void%20setPreference(String%20key%2C%20Object%20value)%20%7B%0A%09%09preferences.setPreference(key%2C%20value)%3B%20%0A%09%7D%20%0A%0A%09%2F%2FRest%20of%20code%0A%7D” message=”Administrator class” highlight=”” provider=”manual”/]

As you can directly see, we have a lot of duplicate code. Every class has it’s own username, password and emailAddress variables and it’s getter and setter methods. Same as the getPreference(String key) method. Imagine you have to add new variables, let’s say firstname and lastname, to all User classes. So you basically write it once, copy-paste the same code into the other two classes. As stated in one of my previous articles copy-pasting is a code smell and should be avoided and replaced by object oriented programming. So, how can we do it better?

Refactoring baby

Without further ado, here is one possible solution:

[pastacode lang=”java” manual=”public%20abstract%20class%20AbstractUser%20%7B%0A%09%0A%09public%20enum%20UserRole%20%7B%20%0A%09%09ADMINISTRATOR%2C%20MAINTAINER%2C%20USER%3B%0A%09%7D%20%0A%09%0A%09private%20String%20username%3B%0A%09private%20String%20password%3B%0A%09private%20String%20emailAddress%3B%0A%09protected%20Preferences%20preferences%3B%0A%09%0A%09private%20UserRole%20userRole%3B%20%0A%09%0A%09public%20AbstractUser(UserRole%20userRole)%20%7B%0A%09%09this.userRole%20%3D%20userRole%3B%20%0A%09%7D%20%0A%09%0A%09public%20void%20getPreference(String%20key)%20%7B%0A%09%09Object%20pref%20%3D%20preferences.getPreference(key%2C%20null)%3B%20%0A%09%09if%20(pref%20%3D%3D%20null)%20%7B%0A%09%09%09throw%20new%20NoSuchElementException(%22No%20preference%20found%20for%20key%20’%22%20%2B%20key%20%2B%20%22’%22)%3B%0A%09%09%7D%20%0A%09%7D%20%0A%09%0A%09%2F%2FRest%20of%20code%0A%20%7D” message=”AbstractUser class” highlight=”” provider=”manual”/]

[pastacode lang=”java” manual=”public%20class%20User%20extends%20AbstractUser%20%7B%20%0A%09%0A%09public%20User()%20%7B%0A%09%09super(UserRole.USER)%3B%20%0A%09%7D%20%0A%7D” message=”User class extending AbstractUser” highlight=”” provider=”manual”/]

[pastacode lang=”java” manual=”public%20class%20Maintainer%20extends%20AbstractUser%20%7B%0A%09%0A%09public%20Maintainer()%20%7B%20%0A%09%09super(UserRole.MAINTAINER)%3B%20%0A%09%7D%20%0A%09%0A%09private%20Map%3CString%2C%20User%3E%20usersToMaintain%20%3D%20new%20HashMap%3CString%2C%20User%3E()%3B%20%0A%09%0A%09%2F%2FRest%20of%20code%20%0A%7D” message=”Maintainer class extending AbstractUser” highlight=”” provider=”manual”/]

[pastacode lang=”java” manual=”public%20class%20Administrator%20extends%20AbstractUser%20%7B%0A%09%0A%09public%20Administrator()%20%7B%20%0A%09%09super(UserRole.ADMINISTRATOR)%3B%20%0A%09%7D%20%0A%09%0A%09private%20Map%3CString%2C%20AbstractUser%3E%20allUsers%20%3D%20new%20HashMap%3CString%2C%20AbstractUser%3E()%3B%20%0A%09%0A%09public%20void%20setPreference(String%20key%2C%20Object%20value)%20%7B%20%0A%09%09preferences.setPreference(key%2C%20value)%3B%20%0A%09%7D%20%0A%09%0A%09%2F%2FRest%20of%20code%20%0A%7D” message=”Administrator class extending AbstractUser” highlight=”” provider=”manual”/]

So now, even if the User.class does not directly have the preferences variable, it still can call the getPreference(String key) method provided by the AbstractUser.class. Same goes for all the getters and setter of the variables username, password and emailAddress. Instead of having three classes wich multiple lines of duplicate code we end up with essentially one abstract class with the information all three classes have in common. Now, if we want to extend all our User classes with firstname and lastname we only have to add these variables into our AbstractUser.class.

What have we learned?

Today we saw that inheritance is a mechanism of creating a class from another class.By letting a subclass inherit from a superclass it automatically has access to all the public and protected variables and methods. This helps you to put code, that is used by multiple classes into one spot. No duplicate code. Easy to maintain and extend classes.

 

Categories: Blog Posts