Adapted from http://math.hws.edu/javanotes/c5/s5.html
this and super
ALTHOUGH THE BASIC IDEAS of object-oriented programming are reasonably simple and clear, they are subtle, they take time to get used to, and there are a lot of details. In this section, we'll look at two keywords, this and super that can be used in any instance of a class.
The Special Keywords this and super used as variables
A static member (variable or method) of a class has a simple name, which can only be used inside the class definition. For use outside the class, it has a full name of the form class-name.simple-name. For example, "System.out" is a static member variable with simple name "out" in the class "System". It's always legal to use the full name of a static member, even within the class where it's defined. Sometimes it's even necessary, as when the simple name of a static member variable is hidden by a local variable of the same name. For example:
public class Student { private static String sName; // Name of the school. private String name; // Name of the student. . . // More variables. . // Constructor. Create a student with specified name. public Student(String sName) { name = sName; System.out.println("Added new student " + sName + "to school " + Student.sName); } // constructor . . // More methods. . } // StudentInstance variables and instance methods also have simple names. The simple name of such an instance member can be used in instance methods in the class where the instance member is defined. Instance members also have full names, but remember that instance variables and methods are actually contained in objects, not classes. The full name of an instance member has to contain a reference to the object that contains the instance member. To get at an instance variable or method from outside the class definition, you need a variable that refers to the object. Then the full name is of the form variable-name.simple-name. For example, "drawString" is the simple name of an instance method in the class "Graphics". Outside the "Graphics" class, in your paint method, you call it with the instance "g" : g.drawString. But suppose you are writing the definition of an instance method in some class. How can you get a reference to the object that contains that instance method? You might need such a reference, for example, if you want to use the full name of an instance variable, because the simple name of the instance variable is hidden by a local variable or parameter.
Java provides a special, predefined variable named "this" that you can use for such purposes. The variable, this, is used in the source code of an instance method to refer to the object that contains the method. This intent of the name, this, is to refer to "this object," the one right here that this very method is in. If x is an instance variable in the same object, then this.x can be used as a full name for that variable. If otherMethod() is an instance method in the same object, then this.otherMethod() could be used to call that method. Whenever the computer executes an instance method, it automatically sets the variable, this, to refer to the object that is being used to call the method.
One common use of this is in constructors. For example:
public class Student { private String name; // Name of the student. . . // More variables. . // Constructor. Create a student with specified name. public Student(String name) { this.name = name; } // constructor . . // More methods. . } // StudentIn the constructor, the instance variable called name is hidden by a parameter name. However, the instance variable can still be referred to by its full name, this.name. In the assignment statement, the value of the formal parameter, name, is assigned to the instance variable, this.name. This is considered to be acceptable style: There is no need to dream up cute new names for formal parameters that are just used to initialize instance variables. You can use the same name for the parameter as for the instance variable.
There are other uses for this. Sometimes, when you are writing an instance method, you need to pass the object that was used to call the method to another method, as an actual parameter. In that case, you can use this as the actual parameter. For example, if you wanted to print out a string representation of the object, you could say "System.out.println(this);". Or you could assign the value of this to another variable in an assignment statement : "fred = this;". In fact, you can do anything with this that you could do with any other variable, except change its value.
Java also defines another special variable, named "super", for use in the definitions of instance methods. The variable super is for use in a subclass. Like this, super refers to the object that contains the method. But it's forgetful. It forgets that the object belongs to the class you are writing, and it remembers only that it belongs to the superclass of that class. The point is that the class can contain additions and modifications to the superclass. super doesn't know about any of those additions and modifications; it can only be used to refer to methods and variables in the superclass.
Let's say that the class that you are writing contains an instance method named doSomething() that overrides a method named doSomething() that your class inherited. Consider the method call super.doSomething(). Now, super doesn't know anything about the doSomething() method in the subclass. It only knows about things in the superclass, so it executes the method named doSomething() that your class inherited from the superclass.
The reason super exists is so you can get access to things in the superclass that are hidden by things in the subclass. For example, super.x always refers to an instance variable named x in the superclass. It is only used if a class contains an instance variable with the same name as an instance variable in its superclass, then an object of that class will actually contain two variables with the same name: one defined as part of the class itself and one defined as part of the superclass. The variable in the subclass does not replace the variable of the same name in the superclass; it merely shadows it. The variable from the superclass can still be accessed, using super, assuming the variable isn't private.
When you write a method in a subclass that has the same signature as a method in its superclass, the method from the superclass is hidden in the same way. We say that the method in the subclass overrides the method from the superclass. Again, however, super can be used to access the method from the superclass.
The major use of super is to make it easy to write a new method that extends the behavior of the inherited method, instead of replacing that behavior entirely. The new method can use super to call the method from the superclass, and then it can add additional code to provide additional behavior. As an example, suppose you have a PairOfDice class that includes a roll() method. Suppose that you want a subclass, GraphicalDice, to represent a pair of dice drawn on the computer screen. The roll() method in the GraphicalDice class should do everything that the roll() method in the PairOfDice class does. We can express this with a call to super.roll(). But in addition to that, the roll() method for a GraphicalDice object has to redraw the dice to show the new values. The GraphicalDice class might look something like this:
public class GraphicalDice extends PairOfDice { // Roll the dice, and redraw them. public void roll() { super.roll(); // Call the roll method from PairOfDice. redraw(); // Call a method to draw the dice. } // roll . . // More stuff, including definition of redraw(). . } // GraphicalDiceNote that this allows you to extend the behavior of the roll() method even if you don't know how the method is implemented in the superclass!
Constructors in Subclasses
Constructors are not inherited. That is, if you extend an existing class to make a subclass, the constructors in the superclass do not become part of the subclass. If you want constructors in the subclass, you have to define new ones from scratch. If you don't define any constructors in the subclass, then the computer will make up a default constructor, with no parameters, for you.
This could be a problem, if there is a constructor in the superclass that does a lot of necessary work. It looks like you might have to repeat all that work in the subclass! This could be a real problem if you don't have the source code to the superclass, and don't know how it works, or if the constructor in the superclass initializes private member variables that you don't even have access to in the subclass!
Obviously, there has to be some fix for this, and there is. It involves the special keyword, super. As the very first statement in a constructor, you can use super to call a constructor from the superclass. As an example, assume that the PairOfDice class has a constructor that takes two integers as parameters. Consider a subclass:
public class GraphicalDice extends PairOfDice { public GraphicalDice() { super(3,4); // Call the constructor from the // PairOfDice class, with parameters 3, 4. initializeGraphics(); // Do some initialization specific // to the GraphicalDice class. } . . // More constructors, methods, variables... . }This is a powerful construct that lets you easily make instances of your class that hold the values you want them to have. You can also use the keyword this in exactly the same way to call another constructor in the same class. This can be useful since it can save you from repeating the same code in several constructors.