理解Java中的OOP和静态

时间:2016-03-23 21:59:48

标签: java oop

假设您有class Aclass BClass A是使用GUI构建框架的主类。它包含所有GUI变量(例如按钮,标签,字符串)以及您将使用的任何方法。 Class A还会创建一个class B对象:

ClassB name = new ClassB();

class B内,您会找到 for循环。现在,一旦for循环完成循环,我想调用位于class A的方法。每当我尝试调用位于class A的方法时,Eclipse建议使用该方法static。我试图避免制作静态方法。有没有办法从class A调用class B的方法而不做任何静态的事情?

A类:

public class Game extends JFrame implements ActionListener {

// init variables
private JPanel contentPane;
private JPanel panel_actions;
private JButton btn_strike;
private JProgressBar progBar_loading;

private Load load;

// create the frame
public dsgsd() {

    load = new Load();

    // frame initializing
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setBounds(100, 100, 890, 480);
    setTitle("BeyondInfinity - Group Project for CS1100");
    getContentPane().setLayout(null);
    setVisible(true);

    // create a root panel
    contentPane = new JPanel();
    contentPane.setLayout(null);
    contentPane.setBounds(0, 0, 884, 451);
    contentPane.setVisible(true);
    getContentPane().add(contentPane);

    // create actions panel for displaying attack buttons
    panel_actions = new JPanel();
    panel_actions.setBorder(new EmptyBorder(10, 10, 10, 10));
    panel_actions.setBounds(10, 306, 854, 68);
    panel_actions.setBackground(new Color(100, 149, 237));
    panel_actions.setLayout(new GridLayout(0, 6, 10, 0));
    panel_actions.setVisible(true);
    contentPane.add(panel_actions);

    // create attack button #1
    btn_strike = new JButton("Strike");
    btn_strike.setFocusable(false);
    btn_strike.setVisible(true);
    btn_strike.addActionListener(this);
    panel_actions.add(btn_strike);

}

// create action listener
public void actionPerformed(ActionEvent evt) {

    if (evt.getSource().equals(btn_strike)) {
        load.start();
    }
}

public void executeTasks() {
    //TODO do something 
}

// set value for the loading bar
public void setProgBar_loading(int val) {
    progBar_loading.setValue(val);
    progBar_loading.repaint();
}


}

B组:

public class Load {
  private Timer timer;
  private int i;

  public void start() {
    // reset loading bar
    Game.setProgBar_loading(0);
    i = 0;

    ActionListener listener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            if (i > 100) {
                timer.stop();
                Game..executeTasks();
            } else
                Game.setProgBar_loading(i++);

        }
    };
    // timer which triggers the actionlistener every 15ms
    timer = new Timer(15, listener);
    timer.start();
  }
}

4 个答案:

答案 0 :(得分:3)

您需要在ClassA内部引用ClassB的实例,以避免使用静态方法。

首先,ClassB需要一个类似于以下内容的字段和构造函数:

private ClassA parent = null;

public ClassB(ClassA parent) {
    this.parent = parent;
}

然后,当您实例化ClassB时,您将传递对当前实例的引用,如下所示:ClassB name = new ClassB(this)

最后,如果您想在ClassB中使用您的方法(让我们假设该方法被称为doSomething(),您可以使用parent.doSomething()

来调用它

答案 1 :(得分:3)

"适当"执行此操作的OOP方法是使用接口。

public interface Loadable {
    void reset();
    void setProgress(int progress);
    void onLoaded();
}

您可以在游戏类

中实现此功能
public class Game extends JFrame implements ActionListener, Loadable {

    private JButton load_button;
    private JProgressBar progressBar;

    public Game() {
        // initialize
    }

    public void executeTasks() {
        //TODO do something
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(load_button)) {
            new Loader().load(this);
        }
    }

    @Override
    public void onLoaded() {
        executeTasks();
    }

    @Override
    public void reset() {
        progressBar.setValue(0);
    }

    @Override
    public void setProgress(int progress) {
        progressBar.setValue(progress);
    }
}

并将其传递给Loader。这样,Loader并不关心您是否正在为其提供Game个对象。您可以加载此Loadable可以加载Loader的任何实现。

public class Loader {
    private Timer timer;
    private int i;

    public void load(final Loadable l) {
        // reset loading bar
        l.reset();
        i = 0;

        ActionListener listener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                l.setProgress(++i);

                if (i >= 100) {
                    timer.stop();
                    l.onLoaded();
                }

            }
        };
        // timer which triggers the actionlistener every 15ms
        timer = new Timer(15, listener);
        timer.start();
    }
}

答案 2 :(得分:1)

您可以调用对象的非静态方法,但只能在上调用静态方法。 See this了解有关两者之间差异的更多信息。为了能够在sublime ./Person.h ./test.cpp ./Person.cpp 类型的对象上调用方法,您必须执行以下操作:

ClassA

请注意,public class ClassA { public method myNonStaticMethod() { ... } } public class ClassB { private ClassA a; public ClassB(ClassA a) { this.a = a; //This makes sure this *object* has a *reference* to an object of *type* ClassA. } public void looping() { //some looping code this.a.myNonStaticMethod(); //Actually call the nonstatic method } } 另一个类的任何类都会引用该,并且可以在该类上调用静态方法,或者实例化一个新的对象该类类型。如果您希望特定对象调用另一个对象的非静态方法,则需要实例化对象本身,它需要引用到另一个对象。

在上面的示例中,import构造函数获得对类型 {{1}的特定对象的引用},其引用名称为ClassB。这将保存到私有成员字段,可以由ClassA类型的对象中的任何非静态方法调用。

答案 3 :(得分:0)

要调用A的任何非静态方法,您需要A的类实例。您是否在B类中有一个?如果你不这样做,那么你就无法调用非静态方法。可以在没有实例的情况下调用静态方法(只要它是可访问的),就像这样A.method1();