Académique Documents
Professionnel Documents
Culture Documents
It often occurs in program design that a class with a basic set of features is extended in various
ways to make more specialised objects. One might design a text editor class which handled plain
text in the default font. This might then be extended to handle various font sizes as well as bold and
italic and to store its contents in rich-text format. A further extension might add the ability for
format paragraphs and to specify different fonts. This reflects sound programming practice which is
to start with a simple solution and to add detail and refinements later. The resulting hierarchy of
classes forms a tree structure.1 It is possible to extend a class anywhere in the hierarchy and thereby
to reuse all the code in the classes above that point.
Some problems fit this model of a class hierarchy very well indeed. For example the entire set of
swing classes use a deep hierarchy which is worthy thinking about as it is a tidy solution to a
complex problem. The diagram below shows this in UML:
1
Computer scientists draw trees upside down with the root at the top and the leaves at the bottom!
1
PRG Notes for reading Week
Another good example of a well-designed class hierarchy is that for Sockets in java. These are
classes which allow point to point communications to be established between ports on computers.
The classes higher in the tree are general, whilst those lowed down support specific protocols such
as HTTP.
The rather contrived examples in java text books tend to consider vehicles or animals, starting with
the lowest common denominator as the root and adding features such as turbochargers or wings at
the lowest levels. These illustrate the idea quite well, but are rather contrived from a programming
point of view. If you are designing software from scratch and can see a clear hierarchy of
abstraction in some aspect of it then you will almost certainly benefit from using an inheritance
hierarchy.2
So the main use of inheritance is to allow code reuse. The code of the classes at the top of a
hierarchy will be exploited by all those below. The user does not have to know how these classes
work to extend them. In Java a class can extend only one other class, a simplification which is
known as single inheritance.
If a method in a derived class has the same signature as one in the base class, then it is said to
override that method.
A derived class can call methods in the baseclass it extends using the super keyword. This can be
very useful in practical examples. Suppose we have a class that draws lines:
It may be that we would like a class that draws a square. Perhaps we wish to do this in a method by
passing the lower left corner coordinate and the length of a side. It would be useful to reuse the
2
A personal note: I started at the other extreme as a programmer, and my first job was developing CAD packages
writing in assembly language. I was an early fan of object oriented programming using Smalltalk and C++. I
appreciated the ability to hide complexity and encapsulate my designs as classes. I was rather slow to use inheritance,
and it took me about five years before I began to spot opportunities to use this abstraction approach. It is more error-
prone in C++ which supports multiple inheritance, and it was Java and C# that have made this concept a natural way of
coding for me. I find that I use inheritance a great deal in C++ as well these days, which has improved my coding
style. C++ remains my language of choice for most programming other than server-side code and real-time embedded
work. Why? It gives more power to the programmer and I prefer to tidy up my own garbage than entrust it to the run-
time environment. I don’t really like my code being slowed down by a virtual machine either. This is not a fashionable
point of view and the trend is to cripple C++ as well… see managed C++ in MS dotNet.
2
PRG Notes for reading Week
class that draws lines and of course we could do that simply by including it in our CLASSPATH
and calling its methods. However it may well be a tidier solution to extend it like this:
The super keyword calls a method in the superclass.3 It can also be used in the constructor of the
derived class to call the superclass constructor, but in this case the super command must be the first
line of the constructor. One can see super as being a close relative of this. The first is a reference
to the baseclass object, the second to the current class object.
Note that when you construct an object, the default base class constructor is called implicitly,
before the body of the derived class constructor is executed. So, objects are constructed top-down
under inheritance. Since every object inherits from the original Object class, the Object()
constructor is always called implicitly. However, you can call a superclass constructor explicitly
using the built-in super keyword, as long as it is the first statement in a constructor.
For example, most Java exception objects inherit from the java.lang.Exception class. If you
wrote your own exception class, say SomeException, you might write it as follows:
3
Exercise for the student: It is probably simpler to use the one moveto and four lineto()
calls using the super keyword to implement the method draw_square(). Rewrite the above
to do just that.
3
PRG Notes for reading Week
implementation). This means it is not possible to create an object of this class with the new
operator. A compiler error will occur if this is attempted. Sometimes such classes are known as
pure base classes. In Java terminology an abstract class is a better name. Many of the class
hierarchies in the Java libraries will have an abstract class at their root. Many people consider this
good programming practice.
In order to use an abstract base class, a subclass is required to override the abstract method or
methods and to provide an implementation. In other words, an abstract class is incomplete and
cannot be instantiated, but can be used as a base class that may be extended:
The protected keyword in front of a variable ensures that this method is visible in the derived class
and can be accessed with the super. syntax. In fact if the classes are in the same package, or both
in the same directory and in no package at all, as has often been the case for PRG then it would be
4
PRG Notes for reading Week
visible in any case. The default scoping rules for Java are that anything in a public class is visible to
all other classes in the same package.
Note that you can only go up one level with super. It is not possible to write super.super….
Since ColouredPoint does not provide an implementation of the plot method, it must be
declared abstract. The SimpleColouredPoint class does implement the inherited plot method.
It would be an error to try to instantiate a Point object or a ColouredPoint object. However,
you can declare a Point reference and initialize it with an instance of a subclass object that
implements the plot method: Point p = new SimpleColouredPoint(a, b, red);
p.plot();
That is references to objects nearer the root in a class hierarchy may be used to point at less generic
classes further from the root, but not the other way round.
Interfaces
There is a second kind of inheritance in Java which is rather different and which implements the
concept of subtyping. In Java, the two kinds of inheritance are made distinct by using different
language syntax. For class inheritance, Java uses the keyword extends as discussed above, while
for interface inheritance Java uses the keyword implements.
An abstract class mixes the idea of data in the form of instance variables, non-abstract
methods, and abstract methods. An abstract class with only static final instance variables and
all abstract methods is called an interface. An interface is a specification, or contract, for a set of
methods that a class that implements the interface must conform to in terms of the type signature
of the methods. The class that implements the interface must provide an implementation for each
method, just as with an abstract method in an abstract class.
So, you can think of an interface as an abstract class with all abstract methods. The interface itself
can have either public, package, private or protected access defined. All methods declared in an
interface are implicitly abstract and implicitly public. It is not necessary, and in fact considered
redundant, to declare a method in an interface to be abstract.
You can define data in an interface, but it is less common to do so. If there are data fields defined in
an interface, then they are implicitly defined to be:
• public
• static
• final
In other words, any data defined in an interface are treated as public constants. Note that a class and
an interface in the same package cannot share the same name. Methods declared in an interface
cannot be declared final. Why not?
5
PRG Notes for reading Week
What is the point of using an interface? It turns out that an interface is a very useful programming
abstraction. It is rather like designing the front panel of an instrument, providing all the knobs,
buttons, dials, indicators and so on that a user would need. One can do that without thinking at all
about what goes on inside the box. This separation of concerns is a key idea to managing
complexity in systems design programming. A very common scenario in developing a system is to
specify an API or Application Programmer’s Interface for users of your work. The Java
documentation is full of references to APIs and it is a very useful idea. We met an API earlier in
looking at database access in Java using JDBC.
I am currently doing some consultancy for an organisation which requires me to segment and read
words from fax transmissions. I started with an API, expressed as an interface4 which indicated
the functionality of the system to be developed for the customer. Having done this, I can develop a
class that implements this interface and the customer can try it out. If I then decide to do it all in a
completely different way and write another class, provided it implements the same interface there
will be little or no need for the customer to change his code.
The idea of an interface proves to be even more fruitful than I can easily explain here at PRG level.
The idea or separating an interface from the code that implements it is the basis of all component
architectures including COM (Microsoft) and EJBs (Sun Java). It facilitates reuse of code at the
binary level which is what is really needed and avoids the mess Microsoft got themselves in with
Windows 3.1 and to some extent 95 which can be described as dll hell!5
Interface inheritance
A class may only extend one other class, but it may implements any number of interfaces.6 An
example of the syntax for using interfaces is:
A stack is a very useful data structure in computer science. It is like a pile of things (see for
example my desk!) and one can only put things onto a stack at the top, and remove them from the
top (attempting anything else on my desk would cause a landslide). There are many possible ways
to implement such a data structure. One could use an array, or perhaps a linked list. The interface
can be the same in either case and thus it is a good idea to separate that from the implementation:
6
PRG Notes for reading Week
Note that the methods in this interface are defined to operate on objects of type Object. Since a
stack is a container type, it is very common to use the base class for all objects, namely Object,
as the type of the arguments and results to a container type. Since all objects ultimately inherit from
class Object, we can always generically refer to any object in the system using an Object
reference.However, when we pop from a stack, we have to explicitly type case from the very
general type Object to a concrete type, so that we can manipulate the object concretely.7
When should you to use an Interface and when an abstract class? Having reviewed their basic
properties, there are two primary differences between interfaces and abstract classes:
• An abstract class can have a mix of abstract and non-abstract methods, so some default
implementations can be defined in the abstract base class. An abstract class can also have
static methods, static data, private and protected methods, etc. In other words, a class is a
class, so it can contain features inherent to a class. The downside to an abstract base class is
that since there is only single inheritance in Java, you can only inherit from one class.
• An interface has a very restricted use, namely, to declare a set of public abstract method
signatures that a subclass is required to implement. Since you can inherit multiple
interfaces, they are often a very useful mechanism to allow a class to implement a number
of standard APIs.
It is usually a good idea to implement an interface when you need to define methods that are to be
explicitly overridden by some subclass. If you then want some of the methods implemented with
default implementations that will be inherited by a subclass, then create an implementation class or
the interface, and have other class inherit (extend) that class, or just use an abstract base class
instead of an interface.
In the examination on Tuesday you might be asked to define a new class, to define an interface, to
extend a class, or to implement an interface. You may also be asked to write a testing method
which most often would be a main(String args[]).
7
Java 1.5 or Tiger Java introduces a way round this called generics. However this won’t compile under CourseMarker
as yet, so we will leave it out of the module. The same applies to enums – another very useful idea in 1,5.