Почему этот метод не использует какие-либо свойства объекта? - PullRequest
1 голос
/ 12 марта 2010

Здесь Я нашел этот код:

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" нет ссылки на "this".

ДОБАВЛЕНО:

Может быть, это связано. В этом коде:

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(...)). Почему это?

Ответы [ 5 ]

3 голосов
/ 12 марта 2010

Хотя 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);
    }
}

Это полностью эквивалентно.

2 голосов
/ 12 марта 2010

Это потому, что this неявно присутствует в пути поиска компилятора. Компилятор будет искать переменную в следующем порядке:

  1. Локальная переменная в текущем блоке
  2. Локальная переменная во внешнем блоке
  3. Параметр метода
  4. Поле в текущем классе (т.е. относительно this)
  5. Поле в родительском классе
1 голос
/ 12 марта 2010

В этой строке есть неявное использование this:

Container c = getContentPane();

getContentPane() эквивалентно this.getContentPane() здесь.

1 голос
/ 12 марта 2010

Я не понимаю, как "сделать что-то" использовать тот факт, что "кадр" является экземпляр класса JFrame

потому что FunWithPanels extends JFrame, и каждый метод, определенный вами в FunWithPanels, будет вызываться для экземпляра FunWithPanels.

1 голос
/ 12 марта 2010

Если я что-то не понимаю, ответ тривиален:

Компилятору не нужен квалификатор 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. См. Принцип замены Лискова для более подробного объяснения. (Примечание: это может или не может быть хорошим дизайном класса, но я не могу много сказать об этом, не зная контекста).

...