Site Search:

Use super and this to access objects and constructors


Back OCAJP



We have used super, this, super() and this() in the code examples before, for example inheritance and polymorphism,  it's time to organize these knowledge and summarize.
  • this keyword is used to reference instance variables and methods declared in current class or subclass. Since using this is the default behavior, this keyword is often omitted. When local variable and instance variable have the same name, local variable hides the instance variable, we then have to use this keyword to reference instance variable.
  • super keyword is used to reference instance variable and methods declared in superclass. When instance variable is redeclared in subclass, the variable in subclass hides the variable in superclass, we then have to use super keyword to reference the variable in superclass.
  • this() or this(parameter list) is used to call other constructors, it has to be the first line in the constructor. If this() don't have parameter, it can be omitted.
  • super()  or super(parameter list) is used to call the superclass's constructor, it has to be the first line in the constructor. If super() don't have parameter, it can be omitted.
  • super(...) and this(...) can not be in the same constructor 
  • So far we only mentioned hiding instance variables and overriding non-static methods declared in superclass, what we didn't mention is what happens for static variables and static methods. We can not redeclare a static method or static variable as non-static in subclass; we can not redeclare a non-static method or non-static variable as static in subclass. Static variable and static method can not be referenced with this or super keyword, they are accessed via class name or accessed directly in the defining class.
The following example shows how to access static/instance variable/method using this and super keyword or without any keyword.


OCAJP>cat test.java 
import java.util.*;
class test {
  public static void main(String...args) throws Exception{
    canCry cancry = new subClass();  //cast to interface, lost method access
    //cancry.cryLoud(); //error: cannot find symbol
    subClass sub = new subClass();
    superClass su = sub;
    System.out.println("public static void getCount()");
    subClass.getCount();
    sub.getCount();
    superClass.getCount();
    su.getCount();  //static method and static variable, accessed via class name
    System.out.println("cry()");
    sub.cry();
    su.cry();  //instance method and instance variable, accessed via object reference
    sub.setRoarVolumn(10000);
    sub.setLowVolumn(10);
    System.out.println("sub.cryLoud(), only declared in subClass, access re-declared variable without this");
    sub.cryLoud();
    //su.cryLoud();  //error: cannot find symbol
    System.out.println("sub.crySuper(), mehtod override, access hidden variable via super");
    sub.crySuper();
    System.out.println("cryLow(), only declared in superClass, access hidden variable without this");
    sub.cryLow();
    su.cryLow();
    System.out.println("crySelf(), only declared in superClass, access hidden variable via this");
    sub.crySelf();
    su.crySelf();
  }
}
interface canCry {
  public void cry();

class subClass extends superClass {
  public static int count = 3;
  public int volumn = 100;
  //public void getCount() {System.out.println("count=0");}  //error: overridden method is static
  public static void getCount() {System.out.println("count="+count);}
  public String name = "subClass";
  public void cry() {System.out.println(name + " cry");}
  public void cryLoud() {System.out.println("roar:"+volumn);}
  public void crySuper() {System.out.println("roar:"+super.volumn);}
  public void setRoarVolumn(int volumn) {this.volumn = volumn;}
  public void setLowVolumn(int volumn) {super.volumn = volumn;}
}
class superClass implements canCry{
  public int volumn = 1;
  public static int count = 1;
  public static void getCount() {System.out.println("count="+count);}
  public String name = "superClass";
  public void cry() {System.out.println(name + " cry");}
  public void cryLow() {System.out.println("low voice:"+volumn);}
  public void crySelf() {System.out.println("low voice:"+this.volumn);}
}
OCAJP>javac test.java 
OCAJP>java test
public static void getCount()
count=3
count=3
count=1
count=1
cry()
subClass cry
subClass cry
sub.cryLoud(), only declared in subClass, access re-declared variable without this
roar:10000
sub.crySuper(), mehtod override, access hidden variable via super
roar:10
cryLow(), only declared in superClass, access hidden variable without this
low voice:10
low voice:10
crySelf(), only declared in superClass, access hidden variable via this
low voice:10
low voice:10


Let's take a look at another example which shows the usage of this() and super() in constructor.


OCAJP>cat test.java 
class test {
  public static void main(String...args) throws Exception{
    subClass sub = new subClass();
    sub.print();
  }
}

class subClass extends superClass{
  int a = 1, b = 1;
  public subClass(int a, int b, String c) {
    super(a, b, c);
    this.a = a; 
    super.b = b; 
    this.c = c; //equivalent to super.c = c; 
    System.out.println("in subClass 3 parameter constructor, a="+a+" b="+b+" c="+c);
  }
  public subClass(int a, int b) {
    this(a, b, "pass in a and b");
    System.out.println("in subClass 2 parameter constructor, a="+a+" b="+b);
  }
  public subClass(int a) {
    this(a, 2);
    System.out.println("in subClass 1 parameter constructor, a="+a);
  }
  public subClass() {
    this(3);
    System.out.println("in subClass override default constructor");
  }
  public void print() {
    System.out.println("after construction, a="+a+" b="+b+" c="+c);
  }
}
class superClass{
  int b = 0;
  String c;
  public superClass(int a, int b, String c) {
    this(b, c);
    System.out.println("in superClass 3 parameter constructor, a="+a);
  }
  public superClass(int b, String c) {
    this(c);
    System.out.println("in superClass 2 parameter constructor, b="+b);
  }
  public superClass(String c) {
    this();
    System.out.println("in superClass 1 parameter constructor, c="+c);
  }
  public superClass() {
    System.out.println("in superClass override default constructor");
  }
}
OCAJP>javac test.java 
OCAJP>java test
in superClass override default constructor
in superClass 1 parameter constructor, c=pass in a and b
in superClass 2 parameter constructor, b=2
in superClass 3 parameter constructor, a=3
in subClass 3 parameter constructor, a=3 b=2 c=pass in a and b
in subClass 2 parameter constructor, a=3 b=2
in subClass 1 parameter constructor, a=3
in subClass override default constructor
after construction, a=3 b=1 c=pass in a and b

Back OCAJP