Я решал некоторые упражнения, чтобы лучше понять, как работают внутренние классы в java. Я нашел одно довольно интересное упражнение. Условие упражнения заключается в том, чтобы printName()
печатать "sout" вместо "main" с минимальными изменениями. Существует его код:
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();
}
}
У нас есть забавная ситуация - у двух классов есть -A и есть-A-соединения. Это означает, что анонимный внутренний класс расширяет внешний класс, а также объекты внутреннего класса имеют ссылки на объекты внешнего класса. Если вы запустите код выше, будет напечатан "main". Ребенок не может вызывать getName()
родителя через наследование. Но внутренний класс child использует ссылку на родительский (внешний класс) для доступа к методу.
Самый простой способ решить эту задачу - изменить модификатор доступа getName()
от private
к чему-либо еще. Таким образом, ребенок может использовать getName()
через наследование и благодаря позднему связыванию "sout" будет напечатан.
Другой способ решить эту задачу - использовать super.getName()
.
private void sout() {
new Solution("sout") {
void printName() {
System.out.println(super.getName());
}
}.printName();
}
И я не понимаю, как это работает. Может кто-нибудь помочь мне понять эту проблему?
Спасибо за попытку)