1

I'm trying to understand the usage of this and super in subclass methods and in subclass constructor:

super class:

public class Animal {
    protected String name;
    protected String age;

    public Animal(String name, String age) {
        this.name = name;
        this.age = age;
    }
}

this and super keywords used in the subclass method:

public class Dog extends Animal {

    public Dog(String name, String age) {
        super(name, age);
    }

    public void display() {
        this.name = "Doggy";
        super.age = "20";
        System.out.println(this.name + " is " + super.age + " years old");
    }
}

What is the difference between "this" and "super" in the above case? And why is it that in the subclass constructor we can't use "this" to initialize the fields inherited from the superclass, as in the below case, but we can use super() to initialize the same fields in the superclass?

public class Dog extends Animal {

    public Dog(String name, String age) {
        this.name = name;
        this.age = age;
    }
...
}
constantem
  • 71
  • 2
  • 6
  • 1
    FWIW, in your 'display' method, you don't need `this` or `super` at all. Their role in that context is to explicitly specify which object you are talking about (and there is only one object there, despite it being defined by two class definitions). – passer-by Dec 21 '21 at 13:56
  • 2
    "*What is the difference between "this" and "super" in the above case?*" in your case there is no difference because you did not redefine fields with *same names* in your subclass. "*And why is it that in the subclass constructor we can't use "this" to initialize the fields inherited from the superclass*" we can but this is not the problem. Issue here is that first instruction in constructor needs to be call to some `super(..)`. It can be left if you wish compiler to generate `super()` but since your superclass doesn't have no-argument constructor you need to call it explicitly. – Pshemo Dec 21 '21 at 13:56
  • 1
    Tldr, please "study" https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.11.2 (Ctrl+f, "this", "super") – xerx593 Dec 21 '21 at 14:09

3 Answers3

2

In display() the this. and super. are not needed. They would only be needed if the child class declared member variables with the same names as the super class:

public static class Animal {
    protected String name;
    protected String age;

    public Animal(String name, String age) {
        this.name = name;
        this.age = age;
    }
}
public static class Dog extends Animal {

    protected String name;   // These are different from the ones
    protected String age;    // in Animal

    public Dog(String name, String age) {
        super(name, age);
        this.name = "Something else";
        this.age = "123";
    }

    public void display() {
        super.name = "Doggy";  // Need super. to differentiate from Dog class's name
        this.age = "20";
        System.out.println(this.name + " is " + this.age + " years old");
        System.out.println(super.name + " is " + super.age + " years old");
    }
}

public static void main (String[] args) throws java.lang.Exception
{
    Dog dog = new Dog("Sparky", "3");
    dog.display();
}

Output is:

Something else is 20 years old
Doggy is 3 years old
001
  • 13,291
  • 5
  • 35
  • 66
1

With this -> you are pointing to the current object, to be more precise to the object that will be created from the current class. With the super you are able to access the fields from the parent class in this case Animal. To be more precise, YES you are able with super to access the age parameter since it's defined in the Animal (the parent class) but all fields that are going to be defined in Dog should be pointed with this. Also notice that in the constructor of Dog you must call super because you defined constructor in Animal saying that those fields will be set on creation of the object and again in Dog you are giving them values.

f.trajkovski
  • 794
  • 9
  • 24
1

this, the keyword, has two separate jobs.

It's exactly like how + means two completely different things in java: 5 + 2 does integer addition, "foo" + "bar" does string concatenation. Same symbol, 2 unrelated jobs. In english, The word bank means both the land next to a river and also a financial institution. Same word, 2 unrelated jobs.

this is no different.

  1. It means 'this object'. There is only one object here: An object of type Dog. There isn't 'a Dog object' and contained inside it a separate 'Animal super object'. That's not how it works. There is just the Dog object, which contains all fields - any fields you defined in Dog, and any field you defined in Animal.

Hence, this.someFieldDefinedInYourSuperClass = foo; is fine, and that makes sense.

  1. It also means: Select a constructor. This version of the this keyword always comes with parentheses immediately following the keyword. this(params); is what it looks like, and it lets you invoke one of your constructors from another one of your constructors. super() is a similar construct that lets you call one of your super constructors. Note that all constructors must neccessarily use one of these; if you fail to do so the compiler injects super(); as first line in your constructor silently.

Example:

public Student(LocalDate birthDate, String name) {
  this(generateNewStudentId(), birthDate, name);
}

public Student(String id, LocalDate birthDate, String name) {
  this.id = id;
  this.birthDate = birthDate;
  this.name = name;
}

here the first usage is simply: Call the other constructor using the provided values. The second (and third and fourth) usages are the 'it is this object' variant.

In your example, you use super(name, age);. This invokes the public Animal(String name, int age) constructor from your superclass. It doesn't "set the name and the age" - it calls that constructor. What that constructor does? Who knows - you'd have to check the source. Maybe the constructor plays Feliz Navidad from the speakers first. You happen to know that it 'just' does this.name = name; this.age = age; but that's just because that's what's currently in Animal.java.

In contrast, this.name = name; means "set the value of this object's name field to the value of the name parameter".

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72