|Java Class Inheritance|
|Written by Mike James|
Page 3 of 5
A class defines a collection of methods and properties that represents a some sort of logically coherent entity. For example a geometric point. However you soon begin to notice that some types of entity form a family tree of things.
The key thing that should alerts you to this situation is when you find yourself saying an A IS A B with some extra features.
In object oriented terms what this is saying is that the class that represents A is essentially B with some additional methods and properties. Overall an A behaves like a B but it has some extras - it is a bit more than a B.
To accommodate this situation we allow a new class to be derived from an existing class by building on its definition.
For example we have a class that represents a 2D Point and perhaps we want a 2D Point that also specifies a color. Now you could say that PointColor is just a Point with a color property.
In this sense we could say that PointColor extends the idea of a Point and in Java this would be written -
What this means exactly is that the definition of the PointColor class starts off from all of the definitions in the Point class. It is as if you have just cut and pasted all of the text in the Point definition into the PointColor definition.
In more technical terms we say that PointColor inherits from Point and this is a specific example of class inheritance.
If you did nothing else at all an instance of the line class would be exactly the same as the point class - it would have setX, setY, getX, getY and so on as members.
In short all of the members of Point are members of PointColor.
What is the good of inheritance?
Well the key lies in the use of the term “extends”. You don’t have to stop with what you have inherited, you can add data and function members to the new class and these are added to what has been inherited.
That is the class that you are extending acts as a basis for your new class - the class you are extending is often called the base class for this reason but the terminology varies. The key idea to get is that when a class extends another it is everything that class is and more.
For example, in the case of the PointColor class we need one more variables to store the color and some get/set methods.
Now the new PointColor class as all of the methods of Point and a new Color property complete with get/set methods. You can use all of the methods of PointColor with no distinction between what is inherited and what newly defined.
Notice that you can't directly access the property variables such as X,Y and Color directly only via the set/get methods. This is also true for the code within PointColor. That is PointColor cannot directly access X and Y, the variables that belong to Point. They are just as much private from PointColor as they are to the rest of the world. PointColor can't get at the internals of Point.
The relationship between PointColor and its base class Point is simple but it can become more complicated. Before classes and inheritance programmers did reuse code by copy and pasting the text of the code. This worked but any changes made to the original code were not passed on to the copied code. With inheritance if you change the base class every class that extends it are also changed in the same way. The inheritance is dynamic and this is both a good and a bad thing. The problem is that changing a base class might break the classes that extend it. It is for this reason that how a base class does its job should be hidden from the classes that extend it so that they cannot make use of something that might well change. This is the reason that extending classes cannot access the private variables and functions of the base class.
What if you inherit a function that doesn’t do the job that you want it to?
No problem, you simply override it!
(Not to be confused with overloading introduced earlier.)
If you create a new function with the same name and signature as an inherited one it is your new member function that wins out and will be used.
That is the new version overrides the old.
For example, Point.Swap() might be better defined, for strange geometric reasons, in PointColor as a function that swaps each coordinate and changes the color in some way. So let's override the version in Point with a new version in PointColor-
Now when you used PC.Swap() it is this new version in PointColor that is used. That is in:
the new overriding Swap function is used. However in
the original Swap is used.
The only problem is that the new Swap function doesn’t work because X and Y are private data members and not even PointColor, a descendant of Point can get at them! A correct version of Swap would have to use the access functions just like any other function outside of the point class -
An alternative would have been to weaken the protection of the private members to protected. Protected is like private in that the outside world cannot get at protected members but classes that extend a base class can access them. This is a weaker sort of protection that allows classes that are based on other classes access to the inner workings - this if best avoided if possible because it makes it more likely that a change to the base class will break the derived classes.
It is also modern Java practice to add an annotation to an overridden method to make sure that you know that it overrides an inherited method: