Java coding: claiming your inheritance

Over the last few articles, we’ve been looking at various aspects of object-oriented programming (OOP) and how it differs from other programming paradigms by concentrating your design on objects rather than procedures.

Using the idea of classes, we’ve been able to build objects that have attributes and methods defining how the object works.

For example, last time we built a software copy of the old Digital Derby computer game and defined a class called ‘Car’, which has numerous attributes, including position parameters ‘x’ and ‘y’ to detail where on the screen frame it sat.

It also has a method called ‘hit’ to determine whether it’s hit another vehicle.

OOP is a fundamental concept any professional programmer will know intimately because it drives much of modern-day app development, from databases to games.

Coders are sometimes seen as a lazy lot — but in a very good way. No-one wants to write any more code than is absolutely necessary because more code usually leads to more mistakes, errors and bugs.

So there’s another important element of OOP to look at called ‘inheritance’.

Is-A relationships

The best way to explain any coding concept is always with code, so make sure you grab the source code pack here.

The Computer.zip file contains Computer.java. It’s a fairly short program, but it’ll help explain how this inheritance concept works.

We all inherit something of our parents — we’ve all heard people say of newborns ‘she has her mother’s eyes’ or similar. If we try to codify that idea, we’d say a child inherits aspects or ‘attributes’ of its parents.

This parent-child relationship idea is often used in programming and in database design, in particular.

Another way of looking at inheritance is by relationships between objects. If we say ‘a car is a vehicle’, we’re saying two things — first, that a car is a type of vehicle, but second, that it inherits the basic attributes of a vehicle.

While it won’t be apparent for now, it’s also worth noting what it’s not saying — it’s not saying that a vehicle is a car.

Any vehicle will have an engine and a number of wheels, for example, and a car has these attributes, but it also has other specific attributes that other vehicles do not — windshield wipers that you won’t find on a motorcycle, for instance.

So we’ve talked about two basic relationship ideas here — ‘is-a’ and ‘has-a’. A car is a vehicle. A car has wheels. The first indicates a relationship to a more generic class of object; the second represents a relationship to other objects.

In general, almost anything that is part of an ‘is-a’ relationship can be modelled using this concept of inheritance.

What’s it look like?

attLet’s get a bit more practical and look at the computer.java code.

We all know what a computer is — it’s a device with a CPU, RAM, storage and an operating system to perform some form of programming work. So in our app, we have a class called ‘Computer’ with those attributes we’ve just mentioned — CPU, RAM, storage and OS.

But as you know, there are many different types of computers — desktops, notebooks, tablets, smartphones, mainframes, servers. They’re all types of computers but importantly for us, each one shares those basic computer attributes — a CPU, RAM, storage and an OS.

Likewise, we can also say a ‘Mobile Device’ is a specific type of computer — it’ll likely have many specific attributes such as whether or not it has a compass and accelerometer, along with a battery life rating, for example.

It still has a CPU, RAM and the rest of it, but has specific bits of its own. To model this, we could just create a new class called ‘MobileDevice’ with CPU, RAM, storage, OS, compass, accelerometer and battery life attributes, but we’d be duplicating attributes that are found in all computers.

The idea of inheritance allows us to define ‘Computer’ as a base class or ‘superclass’ and create a new ‘MobileDevice’ class that includes or ‘extends’ that Computer class.

Look at the Computer.java code and you’ll see the code line:

class MobileDevice extends Computer {

extThis tells Java exactly what we’ve just said — we want to create a new class ‘MobileDevice’ that starts by inheriting or ‘extending’ all of the attributes and methods found in the ‘Computer’ class.

But we can extend this further — a smartphone is a specific type of mobile device. It inherits all of the basic MobileDevice attributes, but has some of its own, for example, a simCardType that a tablet may not.

So we can create another class ‘Smartphone’ that extends ‘MobileDevice’:

class Smartphone extends MobileDevice {

Notice a couple of things. First, each new ‘subclass’ is a more specific version of its ‘superclass’, for example, Smartphone is a subclass of MobileDevice and MobileDevice, a subclass of Computer.

superGoing the other way, we’d say Computer is the superclass of MobileDevice, just as MobileDevice is the superclass of Smartphone.

This also highlights something else — each superclass can have many subclasses, but in many languages such as Java and C#, a subclass can have only one superclass.

Now at this point, some newbies may confuse the idea of subclasses with subsets — a subclass is not a subset of its superclass. If anything, it’s the exact opposite. A car contains all the aspects of a vehicle, but has extra attributes of its own.

The further down the superclass-subclass chain you go, the more specific information about an object you get – a computer can be any one of a number of diverse devices, but a smartphone is a specific type of computer with typically a larger number of attributes.

Inheriting attributes

outSo what does this all mean in practice? If you look at the main() method within the Computer class (our superclass), the first thing we do is create an object called ‘galaxys6’ of class type Smartphone.

The next line is this:

galaxys6.cpuType = “Samsung Exynos 7420”;

Now scroll down and look at the Smartphone class. It only has three attributes listed — simCardType, talkTimeInHours and mobileNetworkType. There’s no mention of ‘cpuType’, yet the code works. So what’s happening?

Our Smartphone class doesn’t have just three attributes — it actually has 10. This is exactly where inheritance comes into play.

The ‘Smartphone’ class extends ‘MobileDevice’, so Smartphone gains or ‘inherits’ all of the MobileDevice attributes.

But also, since MobileDevice is a subclass of ‘Computer’, MobileDevice also inherits the Computer class attributes. That means Smartphone inherits not just the MobileDevice attributes, but also the Computer class attributes.

By association, galaxyS6 has a cpuType attribute because it’s inherited from the Computer class through the class ‘family tree’.

That’s how the Smartphone class can appear to have only three attributes, but in reality has 10 — by inheriting the MobileDevice and Computer class attributes.

One Direction

The thing to remember, however, is that, just in real life, a parent doesn’t inherit from a child. Or to codify that, a superclass does not inherit the attributes of a subclass – it always works in the outward direction only.

So why is inheritance important? Without it, the Smartphone class would need its own copies of the MobileDevice and Computer class attributes, just as the MobileDevice would also need its copies of the Computer class attributes. That’d mean duplicates galore.

Inheritance provides us with a form of what’s often called ‘code reuse’, reusing earlier code so we don’t have to invent the wheel every time.

Essentially, it allows us to just include attributes in a class that are specific to that class, rather than clogging it up with a whole bunch of generic attributes that can be located in an appropriate superclass.

Improving our previous code

ynNow with this new idea of inheritance under our belts, we can go back to our Overtake game and make some much needed improvements.

We’ve included the original game code in the code pack (Overtake.java). If you didn’t read our previous article, Overtake is a software version of the vintage computer game Digital Derby, where your goal is to maximise your score by driving as fast as possible and avoiding slow and on-coming traffic.

Our original code version of the game is built on three classes — Car, SlowCar and CarOnComing. It’s certainly not the neatest of code and contains a fair serve of what I’d call ‘slop’. There’s duplication of attributes and code, unused attributes — slop.

But I did give myself a tight deadline to create something from scratch, highlighting that the faster you try and code, the greater the degree of slop you produce.

More importantly, the original code has three independent classes of car. They are all doing something different, but we can still trim things down by incorporating a superclass called ‘AIvehicle’ and making SlowCar and CarOnComing subclasses of this superclass.

Overtake2

aicar_16x9The new version of Overtake is in Overtake2.zip. The benefit of inheritance here is that by making a superclass and chucking most of the class code there, we can give each subclass the same features and functions without having multiple copies and stuffing them up.

The result is that there’s almost no code left in both subclasses at all.

Polymorphism

polyIt’s said that OOP is built on three pillars — encapsulation, inheritance and a concept somewhat-confusingly called ‘polymorphism’. Poly-what? Polymorphism, which apparently comes from ancient Greek for ‘many forms’.

If we go back to our Computer.java app, we’ve created an instance of class ‘Smartphone’ called ‘galaxyS6’. Now a Samsung Galaxy S6 is obviously a smartphone, but since it has a CPU, RAM, storage and an operating system, we can rightfully say a Galaxy S6 is also a computer.

So ‘galaxys6’ is an instance of ‘Smartphone’, but we can also say it’s an instance of ‘MobileDevice’ and ‘Computer’ — thus, it’s an object of ‘many forms’.

The way the concept of polymorphism works here is that anywhere in code there’s a call for a ‘Computer’ class object, we can plug in a MobileDevice or Smartphone object as well.

In more general terms, we’d say wherever you can put a superclass object, you can also throw in a subclass object.

Look at the ‘showData’ method inside the Computer superclass. The method header expects one parameter to be passed to it — an object of type ‘Computer’ called ‘object’.

But if you look back at the main() method, we call showData with the ‘galaxyS6’ object parameter, which is a Smartphone object. But again, the code works.

Because this method requires what amounts to a superclass object, we can throw any object that is a subclass of that Computer superclass.

Here’s another example — see the code line in the main() method:

MobileDevice aspireA200 = new MobileDevice();

Here, we’ve created a MobileDevice object or instance called ‘aspireA200’. But again, we’ve also dispatched it as a parameter to the showData() method, despite it expecting a Computer class object.

Because MobileDevice is a subclass of Computer, we can use a MobileDevice class object wherever a Computer object is required. Again, our ‘aspireA200’ object takes on more than one form.

Give it a try

For sure, these are complex concepts we’re dealing with here. But the good news is that they’re transferrable to almost any OOP-based programming language, including C# and Objective-C. (You can use C# to code Windows and Windows Phone apps, while Objective-C is the native language for iOS apps).

It’s often said that once you learn how to code one OOP language, it’s not that difficult to learn another. For instance, the basic concepts you use in Java are also used in C#.

Inheritance and polymorphism are fairly abstract ideas but they all add to your toolbox of tricks and provide ways of creating more efficient code.

If you’re head’s still spinning, this is about as abstract as we’ll get in this series. But there are more mountains yet to climb – threads, networking and working with SQL databases, for example.

But the bigger your apps become, the more ideas like inheritance and polymorphism can help keep your code under control.