In this section, you’ll use the this and super keywords to access objects and construc- tors. this and super are implicit object references. These variables are defined and ini- tialized by the JVM for every object in its memory.
Let’s examine the capabilities and use of each of these reference variables.
6.5.1 Object reference: this
The this reference always points to an object’s own instance. Any object can use the this reference to refer to its own instance. Think of the words me, myself, and I: any- one using those words is always referring to oneself, as shown in figure 6.24.
Array to store objects of classes that implement interface Interviewer
Store object of Manager at array position 0 Store object of
HRExecutive at array position 1
Loop through values of array interviewers If object referred to
by interviewer is of class Manager, use casting to retrieve value for its teamSize
If interviewer’s teamSize > 10, call conductInterview
If interviewer’s teamSize <= 10, print message
Otherwise, if object stored is of class HRExecutive, call conductInterview method on object; no casting is required in this case
[7.4] Use super and this to access objects and constructors
428 CHAPTER 6 Working with inheritance
USINGTHISTOACCESSVARIABLESANDMETHODS
You can use the keyword this to refer to all methods and variables that are accessible to a class. For example, here’s a modified definition of the class Employee:
class Employee { String name;
}
The variable name can be accessed in the class Programmer (which extends the class Employee) as follows:
class Programmer extends Employee { void accessEmployeeVariables() { name = "Programmer";
} }
Because there exist members of the class Employee within the class Programmer, the variable name is accessible to an object of Programmer. The variable name can also be accessed in the class Programmer as follows:
class Programmer extends Employee { void accessEmployeeVariables() { this.name = "Programmer";
} }
The this reference is required only when code executing within a method block needs to differentiate between an instance variable and its local variable or method parameters. But some developers use the keyword this all over their code, even when it’s not required. Some use this as a means to differentiate instance variables from local variables or method parameters.
Figure 6.25 shows the constructor of the class Employee, which uses the reference variable this to differentiate between the local and instance variables name, which are declared with the same name.
In the previous example, the class Employee defines an instance variable name. The Employee class constructor also defines a method parameter name, which is effectively a local variable defined within the scope of the method block. Hence, within the scope of the previously defined Employee constructor, there’s a clash of names, and
this = I, me, myself
Figure 6.24 The keyword this can be compared to the words me, myself, and I.
429 Use this and super to access objects and constructors
the local variable will take precedence (covered in section 3.1). Using name within the scope of the Employee class constructor block will implicitly refer to that method’s parameter, not the instance variable. In order to refer to the instance variable name from within the scope of the Employee class constructor, you are obliged to use a this reference.
USINGTHISTOACCESSCONSTRUCTORS
You can also reference one constructor from another by using the keyword this. Here’s an example in which the class Employee defines two constructors, with the sec- ond constructor calling the first one:
class Employee {
String name;
String address;
Employee(String name) { this.name = name;
}
Employee(String name, String address) { this(name);
this.address = address;
} }
To call the default constructor (one that doesn’t accept any method parameters), call this(). Here’s an example:
class Employee {
String name;
String address;
Employee() { name = "NoName";
address = "NoAddress";
}
Employee(String name, String address) { this();
if (name != null) this.name = name;
if (address != null) this.address = address;
} }
class Employee { String name;
Employee(String name) { this.name = name;
}
} Method parameter name
Instance variable name
Figure 6.25 Using the keyword this to differentiate between the method parameter and the instance variable
Instance variables are name and address Constructor that accepts only name Constructor
that accepts name and address
Calls constructor that accepts only name Assigns value of method parameter address to instance variable
Instance variables are name and address Constructor that doesn’t accept any arguments
Constructor that accepts name and address Calls
constructor that doesn’t accept any arguments.
Must be the first statement
in this method. Assigns value of not-null
method parameters
430 CHAPTER 6 Working with inheritance
If present, a call to a constructor from another constructor must be done on the first line of code of the calling constructor.
EXAM TIP this refers to the instance of the class in which it’s used. this can be used to access the inherited members of a base class in the derived class.
USINGTHEKEYWORDTHISINANINTERFACE
With Java 8, you can use the keyword this in an interface’s default method to access its constants and other default and abstract methods. In the following example, the interface Interviewer defines a default method submitInterviewStatus. This method uses this to access itself and its constants or methods:
interface Interviewer { int MIN_SAL = 9999;
default void submitInterviewStatus() { System.out.println(this);
System.out.println(this.MIN_SAL);
System.out.println(this.print());
}
String print();
}
class Manager implements Interviewer { public String print() {
return("I am " + this);
} }
class Foo {
public static void main(String rags[]) { Interviewer m = new Manager();
m.submitInterviewStatus();
} }
You might see a similar output for the preceding code:
Manager@19e0bfd 9999
I am Manager@19e0bfd
EXAM TIP With Java 8, you can use the keyword this in a default method to access the methods of an interface and its constants.
You can’t use the this keyword to access static methods of an interface.
6.5.2 Object reference: super
In the previous section, I discussed how this refers to the object instance itself. Simi- larly, super is also an object reference, but super refers to the direct parent or base class of a class. Think of the words my parent, my base: anyone using those terms is always referring to their direct parent or the base class, as shown in figure 6.26.
431 Use this and super to access objects and constructors
USINGSUPERTOACCESSVARIABLESANDMETHODSOFTHEBASECLASS
The variable reference super can be used to access a variable or method from the base class if there’s a clash between these names. This situation normally occurs when a derived class defines variables and methods with the same name as the base class.
Here’s an example:
class Employee {
String name;
}
class Programmer extends Employee {
String name;
void setNames() {
this.name = "Programmer";
super.name = "Employee";
}
void printNames() {
System.out.println(super.name);
System.out.println(this.name);
} }
class UsingThisAndSuper {
public static void main(String[] args) {
Programmer programmer = new Programmer();
programmer.setNames();
programmer.printNames();
} }
The output of the preceding code is as follows:
Employee Programmer
Similarly, you can use the reference variable super to access a method defined with the same name in the base or the parent class.
super = parent or base class Inherit
Figure 6.26 When a class mentions super, it refers to its direct parent or the base class.
Instance variable—
name, in Employee
Instance variable—
name, in Programmer Assign value
to instance variable—
name, defined in Programmer
Assign value to instance variable—
name, defined in Employee
Print value of instance variable—
name, defined in Employee Print value of instance variable—name, defined in Programmer
Create an object of class Programmer
432 CHAPTER 6 Working with inheritance
USINGSUPERTOACCESSCONSTRUCTORSOFBASECLASS
The reference variable super can also be used to refer to the constructors of the base class in a derived class.
Here’s an example in which the base class, Employee, defines a constructor that assigns default values to its variables. Its derived class calls the base class constructor in its own constructor.
class Employee {
String name;
String address;
Employee(String name, String address) { this.name = name;
this.address = address;
} }
class Programmer extends Employee {
String progLanguage;
Programmer(String name, String address, String progLang) { super(name, address);
this.progLanguage = progLang;
} }
The code at B calls the superclass constructor by passing it the reference variables, name and address, which it accepts itself.
EXAM TIP If present, a call to a superclass’s constructor must be the first statement in a derived class’s constructor. Otherwise, a call to super(); (the no-argument constructor) is inserted automatically by the compiler.
USINGSUPERANDTHISINSTATICMETHODS
The keywords super and this are implicit object references. Because static methods belong to a class, not to objects of a class, you can’t use this and super in static methods. Code that tries to do so won’t compile:
class Employee {
String name;
}
class Programmer extends Employee {
String name;
static void setNames() {
this.name = "Programmer";
super.name = "Employee";
} }
It’s time to attempt the next Twist in the Tale exercise, using the this and super key- words (answer in the appendix).
Instance variables—
name and address Constructor that accepts name and address
Instance variable—
progLanguage Constructor
that accepts values for superclass
variables also Calls
Employee constructor
b
Instance variable—
name, in Employee
Instance variable—
name, in Programmer Won’t
compile—
can’t use this in static
method Won’t compile—can’t use
super in static method
433 Use this and super to access objects and constructors
Let’s modify the definition of the Employee and Programmer classes as follows. What is the output of the class TwistInTale3?
class Employee {
String name = "Emp";
String address = "EmpAddress";
}
class Programmer extends Employee{
String name = "Prog";
void printValues() {
System.out.print(this.name + ":");
System.out.print(this.address + ":");
System.out.print(super.name + ":");
System.out.print(super.address);
} }
class TwistInTale3 {
public static void main(String args[]) { new Programmer().printValues();
} }
a Prog:null:Emp:EmpAddress
b Prog:EmpAddress:Emp:EmpAddress
c Prog::Emp:EmpAddress
d Compilation error
Similarly, you can’t use the keyword this in a static method, defined in an interface:
interface Interviewer { int MIN_SAL = 9999;
static int getMinSalary() { return this.MIN_SAL;
} }
Now let’s move to one of the very important programming concepts: polymorphism.
In the next section, you’ll use abstract classes and interfaces to implement it.
Twist in the Tale 6.3
Won’t compile; can’t use keyword this in a static method
434 CHAPTER 6 Working with inheritance