Почему этот метод не использует никаких свойств объекта?
Вопрос
Здесь Я нашел этот код:
import java.awt.*;
import javax.swing.*;
public class FunWithPanels extends JFrame {
public static void main(String[] args) {
FunWithPanels frame = new FunWithPanels();
frame.doSomething();
}
void doSomething() {
Container c = getContentPane();
JPanel p1 = new JPanel();
p1.setLayout(new BorderLayout());
p1.add(new JButton("A"), BorderLayout.NORTH);
p1.add(new JButton("B"), BorderLayout.WEST);
JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(3, 2));
p2.add(new JButton("F"));
p2.add(new JButton("G"));
p2.add(new JButton("H"));
p2.add(new JButton("I"));
p2.add(new JButton("J"));
p2.add(new JButton("K"));
JPanel p3 = new JPanel();
p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS));
p3.add(new JButton("L"));
p3.add(new JButton("M"));
p3.add(new JButton("N"));
p3.add(new JButton("O"));
p3.add(new JButton("P"));
c.setLayout(new BorderLayout());
c.add(p1, BorderLayout.CENTER);
c.add(p2, BorderLayout.SOUTH);
c.add(p3, BorderLayout.EAST);
pack();
setVisible(true);
}
}
Я не понимаю, как «doSomething» использует тот факт, что «frame» является экземпляром класса JFrame.Мне это непонятно, потому что в коде метода doSomething нет ссылки на «это».
ДОБАВЛЕН:
Возможно, это связано.В этом коде:
import java.awt.*;
import java.applet.Applet;
public class ButtonGrid extends Applet {
public void init() {
setLayout(new GridLayout(3,2));
add(new Button("1"));
add(new Button("2"));
add(new Button("3"));
add(new Button("4"));
add(new Button("5"));
add(new Button("6"));
}
}
В методе «init» мы используем методы «setLayout» и «add» и не привязываем их к конкретному объекту (например objectName.setLayout(...)
).Почему это?
Решение
Пока this
не используется, метод часто использует методы JFrame, особенно в первой строке метода, где он получает панель содержимого. Container c = getContentPane();
Используя this
Ключевое слово сделало бы пример более понятным, но оно вам не нужно.
Пример можно переписать так:
import java.awt.*;
import javax.swing.*;
public class FunWithPanels extends JFrame {
public static void main(String[] args) {
FunWithPanels frame = new FunWithPanels();
frame.doSomething();
}
void doSomething() {
Container c = this.getContentPane();
// .. snip unaltered code
this.pack();
this.setVisible(true);
}
}
Это полностью эквивалентно.
Другие советы
Это потому что this
неявно присутствует в пути поиска компилятора.Компилятор будет искать переменную в следующем порядке:
- Локальная переменная в текущем блоке
- Локальная переменная во внешнем блоке
- Параметр метода
- Поле в текущем классе (т.е.относительно
this
) - Поле в родительском классе
Существует неявное использование this
в этой строке:
Container c = getContentPane();
getContentPane()
эквивалентно this.getContentPane()
здесь.
Я не понимаю, как «досом» использует тот факт, что «рамка» является экземпляром класса JFrame
потому что FunWithPanels extends JFrame
, и каждый метод, который вы определяете в FunWithPanels, будет вызываться в экземпляре FunWithPanels.
Если я ничего не понимаю, то ответ тривиален:
Компилятору не требуется this.
квалификатор для определения того, когда используется член класса.Единственное, что нужно явно использовать this.
это когда происходит конфликт имен, как в
public MyClass {
private Foo foo;
MyClass(Foo foo) {
this.foo = foo;
}
}
Обновлять: Видимо я действительно неправильно понял вопрос...хотя я видимо не одинок в этом.
В любом случае, doSomething()
звонки getContentPane()
, который представляет собой метод JFrame
, и pack()
и setVisible()
из JFrame
родительский класс, Window
.Однако это само по себе не делает необходимым FunWithPanels
расширить JFrame
, поскольку все эти методы публичны и доступны каждому.
Я думаю, что автор так думал FunWithPanels
представляет собой специализированный тип JFrame
, поэтому он стал подклассом.Сюда FunWithPanels
можно использовать везде, где есть общий JFrame
требуется.См. Принцип замены Лискова для получения дополнительных объяснений.(Примечание:это может быть или не быть хорошим дизайном класса, но я не могу много сказать об этом, не зная контекста).