Long time no see. I hope you still remember my recent posting on object-oriented programming. Here is part two, which I hope you are interested in. Today, we are going to have a look at inheritance. If you do not feel familiar enough with classes and objects, please refer to my posting “A Beginner’s Guide to Object Oriented Programming (1)”.
What’s inheritance got to do with programming?
In real life scenarios, an object of a specific class may be able to play different roles. Here is an example:
I am a person, and I have all the attributes and methods that are inherent to any person on this planet. I have certain height and weight. I can sleep(), eat(), and speak(). However, I always play a particular role which depends on the situation I’m in. I’m a teacher, husband, paramedic, scuba diver, runner, motorist, air passenger, …
Now, here comes an awesome fact: Each role that I play can be considered a specialized person. I play many roles, but yet I’m still only one single person. (Luckily … because if this wasn’t the case I’d be suffering from some serious mental disorder.) 😉
There is a term computer science which describes this situation: polymorphism (from Greek polymorphia, which means multiple forms).
Note, that whatever role I’m currently playing I still have all the methods and attributes of a person. For example, my teacher alter ego also has a certain height, weight, and all the capabilities (methods) that any other person may have. But what characteristics and abilities are specific to a teacher? You’ll probably agree that a teacher is able to teach, and that a teacher has to teach a certain number of classes per week.
In order to understand, how the situation above is being modelled in object-oriented programming we need to remember this: A class is a blueprint that can be used to build (instantiate) objects. What we are going to do now is to take this blueprint, put it on a xerox machine, and manually scribble in some features to get a new (extended) blueprint. The new blueprint now allows us to build objects that have both the inherited features and the new features. Of course, we can again make a copy of the new blueprint and add even more features.
The following UML class diagram shows a Teacher class that inherits attributes and methods from a class Person.
In computer science terminology, we say that class Teacher has been derived from class Person. Teacher is the superclass of Person, and Person is a subclass of Teacher. Be aware that I just wrote “the superclass” and “a subclass”. Any class should have only one direct superclass, but it may have more than one subclasses. Java and C#, among other programming languages, enforce single inheritance. (C++ does allow multiple inheritance, but if you feel like you need to use it in your code, this is usually the sign of bad OOP design.)
Person may have a superclass, such as Creature. Likewise, we can derive further classes from Teacher. Consider a school’s principal, for example. He is still a teacher, but he has additional skills, abilities, methods, whatever you want to call it. (Yay! At least in OOP class hierarchy, the principal is down below his school’s teachers.) 😉
Benefits of inheritance
One of the benefits of inheritance is pretty obvious: Reusability, which means that you don’t have to write the same (erroneous) code multiple times. Given the fact that a person, a principal, a teacher, and a plumber eat in exactly the same way, it is enough to implement this method only once.
The second benefit I’d like to mention is very similar to what’s going on in the real world. We know how to eat() and we know about the consequences of eating (some people hate ’em). 😉 However, most of us don’t have a clue about what is going on inside the eat() method. We don’t know the “guts”, so to speak. In our daily life, we appreciate objects that we can just use, without worrying about what’s going on inside. This is called Information hiding.
The third major benefit is Extensibility. As I have mentioned above you can easily enhance your model by adding more subclasses, without impacting the functionality of any of the other existing classes.
There are further benefits that you may discover as you gain experience in object oriented programming. Polymorphism, for example, allows you to write methods that accept objects of different types. The following code in Java shows the definition of method which can be invoked by passing a person, a teacher, a principal, or anything else within the class hierarchy below Person.
public static void giveThisPersonSomethingToEat( Person p ) { p.eat(); }
I hope this tiny and incomplete lesson has helped you to understand the very basics of inheritance. If you have further questions, feel free to ask me in my lectures.
— Andre M. Maier
Source Code Readability
Summer holidays ahead, yay! This will be the time when my job is an enviable one. Having spent the last couple of weeks grading never ending piles of final exams and thesis projects I feel like I deserve it. Most of this time has been dedicated to reading and to understanding sets of twenty or more programs, which all were supposed to solve the same assignment, but followed different approaches, contained a huge variety of logical errors, etc. Some of these programs were extremely hard to read. Working through them can be both tedious and annoying for teachers and college professors. For companies, however, bad source code can be really expensive. Poorly readable code is a ticking time bomb, in fact.
If you are an experienced professional programmer you probably know that every programmer has his or her personal “handwriting”. You merely have to look at some lines of code and you instantly know who the author was (or wasn’t). In this posting I’m not going to preach a certain “handwriting”. It only concentrates on the most important rules to improve the readability of your code. Programming is similar to speaking a language. A slight accent can make you sound sexy, whereas a strong accent may negatively impact the intelligibility of what you are saying.
1. Choose names wisely!
Always use appropriate names when naming variables, methods, parameters, attributes, constants, classes, and so on. If a variable is used for, say, counting events, name it numberOfEvents rather than n. You will notice that code like this requires far less comments. (Reading comments is time consuming!)
Boolean variables may be true or false. If you put is or has in front of the actual variable name (e.g. isEmpty), the name automatically explains that if the value is true.
Variables should express the fact that an action is triggered when they are executed. They contain a set of instructions, so they do something. Java Code Conventions, for example, recommend to let the name begin with a verb.
Find out if there are any code conventions for your programming language and/or platform and stick to them as close as possible.
Here is an example of what will happen when conventions are ignored: Let’s have a look at the following two lines from a Java program.
If you asked an experienced Java programmer which of the methods is static, he would most probably assume that the correct answer was m1. He might be right in perhaps more than 90% of all Java programs there are in the world. However, if somewhere in the program A is declared to be …
… his answer is 100% wrong. According to the Sun Java Code Conventions the line above should be
instead. Not paying attention to upper or lower case is a tiny little sloppiness which could significantly reduce the maintainability of your program.
2. Indent, align, and break the line!
The general idea of indentation is to kind of “visualize” the structure of a program. Classes may contain methods. Methods (or functions) may contain control structures. Control structures may contain nested control structures, … you get the point.
When closing an indented block make sure to place the closing bracket exactly at the appropriate level. If you ever had to debug a “} expected” compiler error in an unindented program with more than three nested blocks, you know what I’m talking about.
Proper alignment and use of line breaks not only makes your code look clean and tidy, but it also provides for better readability.
Some companies have very strict code conventions regarding indentation, line breaks, spaces, and so on. Whatever convention you’re following, be consistent!
This particularly applies to the usage of tabs in your program. Do not mix tabs and spaces! This can drive you nuts if you reopen or print your source code file. Be aware, that most IDEs provide tab-based automatic indentation by default. If you accidentally mixed tabs and spaces, check your IDEs preferences and keep an eye out for an option that is called “convert tabs to spaces” or something like that. Some people recommend to generally avoid tabs in source code.
3. Curly Brackets – Not just a matter of taste!
There is one subject among programmers which is like discussing religion. It is the simple question whether this
or that
if( x ) { // some code }
placement of curly brackets is better. Some people claim that the second style was easier to understand for beginners. Other people say that the opening bracket belongs to the control statement and therefore should not waste a separate line of code.
Many of my students say it doesn’t matter at all, so they seize the opportunity to try out all kinds of different styles in their final project.
This of course does not contribute to good source code readability. As to readability it doesn’t matter which style you are using as long as you keep using one style consistently.
If you are not sure which style you should be using for your program, have a look at the source code of the libraries that come with your compiler. Also, you should be aware that if you are using a style that is not commonly used in this particular programming language, you might betray yourself as being unexperienced in that language. A Java programmer who uses the second style from above may be asked: “You don’t do Java very often, right? Looks like you normally do C or something.” So when in Rome, do as the Romans do. 🙂
In case you are interested in more styles that have been invented, check out the following link: http://en.wikipedia.org/wiki/Indent_style
4. Add comments, but add them carefully!
Back in the late 80s I had been taking Pascal programming classes at school. My teacher always said: “There has to be one comment for each line of code!”. I hate to say this about things my teachers said, but this was blatant nonsense.
When you comply with all of the previously discussed rules, you will notice that you won’t need a large number of comments in your program. A comment should always explain why you wrote the code, not what the code does from the computer’s perspective. As this is difficult to explain, I’ll show you an example.
Always remember that any other person who needs to understand your source code is someone who knows the syntax and semantics of your programming language. So don’t explain the obvious.
What is not directly visible from the code is both the general context (overview) and why the code has been added. Many programmers prefer to write comments before writing the code.
In some programming languages there are even strict conventions on comments. Here is an example from Java which shows you how pedantic these can be.
Whether you are pedantic or not, you should always be familiar with the conventions that apply to your programming language. By the time when you want to have your own code added to the API of this language you have to be pedantic.
I’d be happy enough if my students followed the most basic rules, which are easy to comply with.
Well, that’s all for today. Have a great weekend!
— Andre M. Maier