This is a very important feature of Java and object oriented programming. Each of the classes has its own version of bigger() that is appropriate to it. The user only has to know that they should call bigger() on an instance and they will get the right value. If you need to access the version of the method that is part of the parent, you can use the super reference.
For example, the play() method in wind could call the version in instrument
by this syntax.
super.play(n);While it is possible to override the definition of data variables, this is not recommended. It can get very confusing which version you mean. It is possible to prevent child classes from overriding a method. If it is marked final, then the children must use the parent method.
Using a pointer to the base class, the program can point at a variety
of objects of the derived classes and when the overridden function is called,
it is the one for the type of the object being pointed at.
The code for an example is here.
There are three classes in the hierarchy here.
The parent class (instrument) is here.
This has a child class .
Thegrandchild class is here.
Thedriver code is here.
Now let's look at the output.
Run the tune method on a wind instance wind::play Run the tune method on a reed instance reed::play Set music to flute and run play wind::play Set music to oboe and run play reed::playThe function to be called is determined at run time (late binding). This technique allows us to write functions like tune() that will work for any derived class from a base class. It is easier to extend the classes because tune() still works for other classes derived from instrument. Like drum or guitar. It will also work for lower levels. If class brass is derived from wind, tune() still works. If there is no overridden functions, the one next up the hierarchy is used. Examine the brass class and a new driver to see this. Notice that when tune() is used on an instance of brass, the play() method of it's parent, wind, is used.
Run the tune method on a wind instance wind::play Run the tune method on a reed instance reed::play Run the tune method on a brass instance wind::play Set music to flute and run play wind::play Set music to oboe and run play reed::play Set music to cornet and run play wind::play
Now let's walk through some of the example code from the book to see some of the same ideas in a more concrete example. The code for this is here and on the CD-ROM that came with the book.
We have used listener interfaces to implement GUI actions. When we made a small class to implement the listener interface, we had to override all the methods of the interface, even the ones we weren't going to use. There is another way to handle this without cluttering up the code with a bunch of empty method definitions.
For most of the listener interfaces, there is a corresponding adaptor class. An adaptor class is very simple. It implements the interface we are interested in and provides empty methods for all the interface methods. We can make a class that extends the adaptor class, only overriding the methods we are interested in.
If we used the Interface, we would need to provide empty methods for all the methods in the interface that we didn't need.
private static class GenericWindowListener implements WindowListener { //----------------------------------------------------------------- // Terminates the program when the window is closed. //----------------------------------------------------------------- public void windowClosing (WindowEvent event) { System.exit(0); } public void windowActivated (WindowEvent event){} public void windowClosed (WindowEvent event){} public void windowDeactivated (WindowEvent event){} public void windowDeiconified (WindowEvent event){} public void windowIconified (WindowEvent event){} public void windowOpened (WindowEvent event){} } // window listenerBut with the adaptor class, we only need to override the method we are interested in. All the other methods in the interface already have empty methods provided for us in the class.
private static class GenericWindowListener extends WindowAdapter { //----------------------------------------------------------------- // Terminates the program when the window is closed. //----------------------------------------------------------------- public void windowClosing (WindowEvent event) { System.exit(0); } } // window listener