我是一个java新手,并且在StackOverflow错误/能够在类之间访问文件的能力方面存在一个非常令人困惑的问题。我知道潜在的原因可能是我有一些递归调用,但修复它的语法正在逃避我。我认为它与如何通过扩展另一个类来链接类有关 - 但是,如果InputScreen类没有扩展ViewController,我无法访问那里需要的方法。我把下面的高级代码(制作程序来跟踪汽油里程)。
目标是能够打开包含一些历史里程数据的xml文件(使用doOpenAsXML()方法),然后允许用户将数据添加到某些文本字段(在InputScreen类中定义),添加另一个数据指向ArrayList,然后使用doSaveAsXML方法保存。
任何人都有关于如何使这项工作的想法?感谢!!!
// Simple main just opens a ViewController window
public class MpgTracking {
public static void main(String[] args) {
ViewController cl = new ViewController();
cl.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cl.setVisible(true);
} // end main
}
public class ViewController extends JFrame {
// the array list that I want to fill using the historical data
public ArrayList<MpgRecord> hist;
public ViewController() {
doOpenAsXML(); // open historical data, put into 'hist'
InputScreen home = new InputScreen ();
}
public void doSaveAsXML() {
// ...long block to save in correct xml format
}
public void doOpenAsXML() {
// ...long block to open in correct xml format
}
}
public class InputScreen extends ViewController {
// statements to define a screen with text fields and a 'Save' button
// statements to create a listener on the Save button
// statements to add to the ArrayList hist, opened in the ViewController method
doSaveAsXML();
}
答案 0 :(得分:1)
你是说InputScreen扩展了ViewController?这似乎是构造函数中的无限递归循环。另外,
public ViewController() {
doOpenAsXML(); // open historical data, put into 'hist'
InputScreen home = new InputScreen ();
}
什么都不做。您创建一个新的InputScreen将其设置为变量home,并在构造函数完成后立即获取GCed。
答案 1 :(得分:1)
这似乎是您问题的根本原因:
但是,如果InputScreen类没有扩展ViewController,我就无法访问那里需要的方法。
要访问另一个类中的(非静态)方法,您需要此类的对象。在您的情况下,InputStream需要拥有一个ViewController对象,而不是 一个ViewController对象。 (在同一行中,ViewController不应该 一个JFrame,但有一个 - 虽然这不会给这里带来问题。)
如果你改变了这个,你就不会得到你的构造函数循环。
public class ViewController {
...
public ViewController() {
doOpenAsXML(); // open historical data, put into 'hist'
InputScreen home = new InputScreen (this); // give myself to our new InputScreen.
// do something with home
}
public void doSaveAsXML() {
// ...long block to save in correct xml format
}
public void doOpenAsXML() {
// ...long block to open in correct xml format
}
}
public class InputScreen {
private ViewController controller;
public InputScreen(ViewController contr) {
this.controller = contr;
}
void someMethod() {
// statements to define a screen with text fields and a 'Save' button
// statements to create a listener on the Save button
// statements to add to the ArrayList hist, opened in the ViewController method
controller.doSaveAsXML();
}
}
答案 2 :(得分:0)
简答:Composition over inheritance。 Program against interfaces。 Principle of Least Privilege。 Role interfaces。
我建议你在阅读我的帖子后对他们做谷歌;)
首先,您不需要InputStream
继承ViewController
,因为VieController.doSaveAsXML()
是公开的。
即使它具有private | protected | package可见性,我们也不应仅使用继承来访问我们不可见的其他类的方法。继承是继承,优化或扩展行为,而不是访问方法。
您始终可以将控制器作为参数类型传递给输入流。如果您的输入流需要访问控制器中的所有方法,请按原样传递控制器(或让控制器实现包含其中所有方法的接口。)
首先要注意的重要事项是您的InputStream
并不真正需要访问控制器。它只需要访问可以为其执行file opening
个功能的内容 - 它需要file opener
。
需要注意的第二个重要事项是控制器(通常)不需要知道如何打开文件。控制器通常是组织者或协调器(因为没有更好的词。)因此,它不需要是文件开启器(或实现文件打开逻辑本身。)控制器只需要引用aa {{1 }}。与file opener
一样,input stream
只需将controller
委托给file opening logic
。
换句话说:
file opener
无论你是如何使一切都与界面处理程序相关,这是我们必须对每个项目做出的设计决策。但这种方法(或受其启发的方法)通常是要走的路。以这种方式(但并非不可能)提出周期性依赖性要困难得多,当它们确实发生时,它们是配置问题,而不是对象模型的内在问题。
希望它有所帮助。