StackOverflow混乱

时间:2011-02-06 20:51:37

标签: java stack-overflow

我是一个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(); }

3 个答案:

答案 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 inheritanceProgram against interfacesPrinciple of Least PrivilegeRole interfaces

我建议你在阅读我的帖子后对他们做谷歌;)

首先,您不需要InputStream继承ViewController,因为VieController.doSaveAsXML()是公开的。

即使它具有private | protected | package可见性,我们也不应仅使用继承来访问我们不可见的其他类的方法。继承是继承优化扩展行为,而不是访问方法。

您始终可以将控制器作为参数类型传递给输入流。如果您的输入流需要访问控制器中的所有方法,请按原样传递控制器(或让控制器实现包含其中所有方法的接口。)

首先要注意的重要事项是您的InputStream并不真正需要访问控制器。它只需要访问可以为其执行file opening个功能的内容 - 它需要file opener

需要注意的第二个重要事项是控制器(通常)不需要知道如何打开文件。控制器通常是组织者或协调器(因为没有更好的词。)因此,它不需要是文件开启器(或实现文件打开逻辑本身。)控制器只需要引用aa {{1 }}。与file opener一样,input stream只需将controller委托给file opening logic

换句话说:

  1. 您的输入流需要 访问文件开启者
  2. 您的控制器也只需要 有权访问文件开启者
  3. 你的控制器初始化你的 输入流,所以,它需要 在期间传递文件开启者 初始化
  4. 因为上述,控制器 本身需要接收, 实例化或配置一个 文件开启者本身。
  5. 因为文件开启者是外部的 流和控制器, 文件开启者应该是一个 界面(可以实现 通过xml文件打开器或任何开启器 就此而言。)
  6. java伪代码:

    file opener

    无论你是如何使一切都与界面处理程序相关,这是我们必须对每个项目做出的设计决策。但这种方法(或受其启发的方法)通常是要走的路。以这种方式(但并非不可能)提出周期性依赖性要困难得多,当它们确实发生时,它们是配置问题,而不是对象模型的内在问题。

    希望它有所帮助。