![]() |
|||
![]() ![]() |
![]() |
![]()
|
![]() |
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 lets 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 Frames hide() method), but it doesnt 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 weve shadowed that method with our own handleEvent(). Once weve 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. Heres 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, its 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 dont explicitly choose a different one. This can lead to annoying bugs that prevent you from instantiating a subclass if the superclass doesnt 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 youre being warned doesnt 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); } }
|
![]() |
|