从另一个类访问变量的最佳方式?



我需要访问另一个类中的变量,我使用了下面描述的两种不同的方法。

我的问题是这两种方法中哪一种更可取,为什么两者都很好地工作-或者有另一种更好的方法吗?我也使用过内部类,但是当代码行数越来越大时,这很不方便。

在下面的测试代码中,注释的星号代表不同的文件:

import java.awt.EventQueue;
import javax.swing.JFrame;
public class Test {   
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() { 
MainFrame f = new MainFrame("Testing",50,50);
f.setResizable(false);                  
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});   
}
}
//**********************************************************************
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class MainFrame extends JFrame {
public MainFrame(String title,int x,int y) {
setTitle(title);
this.setLocation(x, y);     
UpperPanel pUp=new UpperPanel();
add(pUp, BorderLayout.NORTH);
LowerPanel pLow=new LowerPanel();
add(pLow, BorderLayout.SOUTH);
pack();
}
}

现在你可以在下面看到,UpperPanel必须从LowerPanel访问JButtons, LowerPanel必须从UpperPanel访问菜单。出于这个原因,我可以将pUp作为参数传递给LowerPanel构造函数,但我不能将pLow作为参数传递给UpperPanel,因为它还没有创建。

因此我使用了2个方法,一个声明相关类的实例,另一个使用静态变量。上面的两个类在每种方法中都是相同的。

下面是第一种情况下面板的代码:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPanel;
public class LowerPanel extends JPanel implements ActionListener {
static JButton butEnableMenu;
static JButton butEnableBut1;
public LowerPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
butEnableMenu=new JButton("Enable menu");
butEnableMenu.setEnabled(true);
butEnableMenu.addActionListener(this);      
add(butEnableMenu);
butEnableBut1=new JButton("Enable first button");
butEnableBut1.setEnabled(false);    
butEnableBut1.addActionListener(this);  
add(butEnableBut1);     
}
public void actionPerformed(ActionEvent e) {    
UpperPanel up = null;
Object clicked=e.getSource();
JMenu mnu=up.myMenuBar.getMenu(0);
if(clicked.equals(butEnableMenu)) {
mnu.setEnabled(true);
butEnableMenu.setEnabled(false);
}
else if(clicked.equals(butEnableBut1)) {
butEnableMenu.setEnabled(true);
butEnableBut1.setEnabled(false);
}
}
}
//**********************************************************************
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class UpperPanel extends JPanel {
static JMenuBar myMenuBar;
public UpperPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
myMenuBar=new JMenuBar();
JMenu but2=new JMenu("2nd button");
JMenuItem enableBut2=new JMenuItem("Enable");
but2.setEnabled(false);
enableBut2.addActionListener(new menuActionListener());
myMenuBar.add(but2);
but2.add(enableBut2);
add(myMenuBar);     
}
}
class menuActionListener implements ActionListener {
static String clickedMenuItem=null;
LowerPanel lp;
public void actionPerformed(ActionEvent e) {
clickedMenuItem=e.getActionCommand();
JMenuItem mnuItm=(JMenuItem)e.getSource();
JPopupMenu pmen = (JPopupMenu)mnuItm.getParent();
JMenu pmnu =(JMenu)pmen.getInvoker();
if(clickedMenuItem.equals("Enable")) {
pmnu.setEnabled(false);
lp.butEnableBut1.setEnabled(true);
}
}
}

第二种情况是:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class UpperPanel extends JPanel {
static JMenuBar myMenuBar;
public UpperPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
myMenuBar=new JMenuBar();
JMenu but2=new JMenu("2nd button");
JMenuItem enableBut2=new JMenuItem("Enable");
but2.setEnabled(false);
enableBut2.addActionListener(new menuActionListener());
myMenuBar.add(but2);
but2.add(enableBut2);
add(myMenuBar); 
}
}
class menuActionListener implements ActionListener {
static String clickedMenuItem=null;
public void actionPerformed(ActionEvent e) {
clickedMenuItem=e.getActionCommand();
JMenuItem mnuItm=(JMenuItem)e.getSource();
JPopupMenu jpm = (JPopupMenu)mnuItm.getParent();
JMenu pmnu =(JMenu)jpm.getInvoker();
if(clickedMenuItem.equals("Enable")) {
pmnu.setEnabled(false);
LowerPanel.butEnableBut1.setEnabled(true);
}
}
}
//**********************************************************************
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPanel;
public class LowerPanel extends JPanel implements ActionListener {
static JButton butEnableMenu;
static JButton butEnableBut1;
public LowerPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
butEnableMenu=new JButton("Enable menu");
butEnableMenu.setEnabled(true);
butEnableMenu.addActionListener(this);      
add(butEnableMenu);
butEnableBut1=new JButton("Enable first button");
butEnableBut1.setEnabled(false);    
butEnableBut1.addActionListener(this);  
add(butEnableBut1);
}
public void actionPerformed(ActionEvent e) {        
Object clicked=e.getSource();
JMenu mnu=UpperPanel.myMenuBar.getMenu(0);
if(clicked.equals(butEnableMenu)) {
mnu.setEnabled(true);
butEnableMenu.setEnabled(false);
}
else if(clicked.equals(butEnableBut1)) {
butEnableMenu.setEnabled(true);
butEnableBut1.setEnabled(false);
}
}
}

通常有两种方法从另一个类访问变量:

  1. 创建该类的对象。然后,该对象拥有该类作用域中分配给它的所有变量。例如:
Test t = new Test();
t.name = "test";
  1. 您也可以创建一个静态变量。然后将变量赋值给类,而不是该类的对象。这样你就不需要创建一个对象,但是类的所有实例将共享同一个变量。
//In the scope of the class
static String name; 
-------------------------
//when classing the class
Test.name = "The Name of the Test";

如果你不想每次都创建一个类的新实例,并且总是使用同一个实例,你可以创建一个单例对象。你写一个getter方法来获取对象。它看起来像这样:

public class Test {
Test t;
public static void main(String[] args) {
t = new Test();
}

public Test getTest() {
if (t != null) {
return t;
} else {
t = new Test();
return t;
}
}
}

我看到你在使用JFrame。那么您可能希望将其设置为单例。否则,每次调用JFrame时都将打开一个新的实例,不建议这样做。这回答你的问题了吗?