Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click Here!
Click Here!
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


The this reference

The special reference this always refers to the current object. For example, the statement

     int j = this.x;

sets the variable j equal to the x field of this object. Using the this reference is normally optional. Using “int j = x” would work equally well. However, on occasion, a variable declared inside a method can shadow a field. This is most common in constructors. For example, consider this elaboration of the 3Dpoint class:

     public class 3DPoint {

      double x;
      double y;
      double z;

      public 3DPoint (double x, double y, double z) {

       this.x = x;
       this.y = y;
       this.z = z;

      }

      //  other methods...

     }

The three arguments to the constructor — x, y, and z — shadow the fields of the same name. Inside the 3DPoint constructor, x, y, and z no longer refer to the fields of the object but rather to the arguments to the method. However, this.x, this.y, and this.z still refer to the fields x, y, and z.

The this keyword can also be used to call a different constructor in the current class. With this usage, this is not, strictly speaking, a reference. The this keyword can be used this way only in the first statement of another constructor. For example, to call the 3DPoint (double x, double y, double z) constructor from the noargs 3DPoint() constructor, you would write

     public 3DPoint () {

      this(0, 0, 0);

     }

This technique is especially common in polymorphic constructors. Arguments not passed to one constructor are filled in with default values as a call to another constructor.

The super reference

The this reference refers to methods and fields of the current object. The super reference refers to the methods and fields of the immediate superclass. You need to use the super prefix only if a field or method in the subclass has the same name as a field or method in the superclass.

For example, the java.awt.Component class has a handleEvent() method, so its subclasses do, too. Specifically, java.awt.Container has a handleEvent() method; java.awt.Frame() has a handleEvent() method; and any subclass of java.awt.Frame that you write has a handleEvent() method. Now let’s suppose that you want to write a subclass of Frame that allows the window (that is, the Frame) to be closed. One way to do this is to override handleEvent() in your subclass of Frame so that it handles WINDOW_DESTROY events. That method might look like this:

     public boolean handleEvent(Event e) {

      if (e.id == Event.WINDOW_DESTROY) {
       hide();
       return true;
      }
      else return false;

     }

This method will close the window (by calling the Frame’s hide() method), but it doesn’t handle any other events. It completely misses mouse clicks, key presses, action events, and more. This would normally be handled by the handleEvent() method of the Component class, but we’ve shadowed that method with our own handleEvent(). Once we’ve finished our custom processing of the WINDOW_DESTROY event, we want to pass all other events to the handleEvent() method of java.awt.Component. The super keyword acts like a reference to that class that lets us do that. Instead of writing “else return false;”, write “else return super.handleEvent(e);”. This calls the handleEvent() method in the superclass rather than the handleEvent() method in this class. Here’s the complete method:

     public boolean handleEvent(Event e) {

      if (e.id == Event.WINDOW_DESTROY) {
       hide();
       return true;
      }
      else return super.handleEvent(e);

     }

Using the super keyword like this finds the nearest method with a matching signature. In this case, it’s the handleEvent() method in java.awt.Component. If there were a handleEvent() method in java.awt.Frame or java.awt.Container, that would be called instead.

Like the this keyword, super also has a non-reference meaning inside a constructor. If you use super() as the first statement in a constructor, it calls the matching constructor in the immediate superclass.

If you do not include an explicit call to super() as the first statement in your constructor, then the compiler will insert such a call into the byte code. The compiler always chooses the noargs super() constructor if you don’t explicitly choose a different one. This can lead to annoying bugs that prevent you from instantiating a subclass if the superclass doesn’t have a public or protected noargs constructor. For example, consider this incorrect Java program:

     public class superclass {

      public superclass(int i) {

      }

     }

     class subclass extends superclass {

      subclass() {

      }

     }

If you try to compile this program, you get the error message “No constructor matching superclass() found in class superclass: superclass.java line 12”. This is a common problem for novices. What you should do to fix this is completely un-obvious, because you never actually called the superclass() constructor that you’re being warned doesn’t exist. The solution is either add a noargs constructor to the superclass or to call the superclass(int i) constructor in the first line of the subclass. For example,

     class subclass extends superclass {

      subclass() {
        super(0);
      }

     }


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.