I have a class
public class A {
public String attr ="A attribute";
public void method() {
System.out.println(this+" , "+this.attr);
}
public String toString() {
return("Object A");
}
}
and another class that inherits from it
public class B extends A{
public String attr = "B attribute";
public void method() {
super.method();
}
public String toString() {
return("Object B");
}
}
Note that the method()
of B
is simply a wrapper for method()
of A
.
When I run the following code
B b = new B();
b.method();
I get Object B , A attribute
as output which means that, this
and this.attr
accessed different things. Why is that the case?
Shouldn't System.out.println(this)
refer to the toString()
method of class A
?
By declaring a method with a same name as parent class, you override it, that is, replace the original behaviour. But if you declare a field with a same name, you effectively hide it, making it inaccessible from that subclass, but only by super.field
. See oracle docs on variable hiding, as well as using the keyword super. Note that it is not recommended to use variable hiding, as it creates exactly the kind of confusion you're experiencing.
By calling super.method()
, printing this
results in calling the toString
method, which was in fact overridden - so that's the reason why it prints "Object B", as you've called the method on an instance of B. But the this
in this.attr
actually refers to the parent object, as you're calling the method
from the parent class (by super.method()
).