I was solving some exercises to understand better how inner classes in java work. I found one quite interesting exercise. The condition of the exercise is to make printName()
print "sout" instead of "main" with minimum changes. There is its code:
public class Solution {
private String name;
Solution(String name) {
this.name = name;
}
private String getName() {
return name;
}
private void sout() {
new Solution("sout") {
void printName() {
System.out.println(getName());
// the line above is an equivalent to:
// System.out.println(Solution.this.getName);
}
}.printName();
}
public static void main(String[] args) {
new Solution("main").sout();
}
}
We've got an amusing situation - the two classes have is-A and has-A connections.
It means that the anonymous inner class extends the outer class and also objects of the inner class have references to the objects of the outer class.
If you run the code above, "main" will be printed. The child cannot invoke getName()
of the parent through inheritance. But the child being inner class uses reference to parent(outer class) to access the method.
The simplest way to solve this task is to change the access modifier of getName()
from private
to anything else. So the child is able to use getName()
through inheritance and thanks to late binding "sout" will be printed.
The another way to solve this task is to use super.getName()
.
private void sout() {
new Solution("sout") {
void printName() {
System.out.println(super.getName());
}
}.printName();
}
And I cannot understand how it works. Can someone help me to understand this problem?
Thank you for trying)