StackOverflow 混乱
我是一个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
}
公共类 ViewController 扩展 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
}
}
公共类 InputScreen 扩展 ViewController {
// 定义带有文本字段和“保存”按钮的屏幕的语句
// 在“保存”按钮上创建侦听器的语句
// 添加到 ArrayList hist 的语句,在 ViewController 方法中打开
doSaveAsXML();
}
I'm a java newbie, and am having a very confusing issue with StackOverflow errors / ability to access files between classes. I understand that the underlying cause is likely that I have some recursive call, but the syntax of fixing it is escaping me. I think it has something to do with how the classes are linked through one extending another -- but, if the InputScreen class doesn't extend the ViewController, I can't access the methods there that I need. I've put the high-level code below (making a program to track gas mileage).
Goal of this is to be able to open an xml file with some historical mileage data (using the doOpenAsXML() method), then allow the user to add data to some text fields (defined in the InputScreen class), add another data point to the ArrayList, and then save using the doSaveAsXML method.
Anyone have ideas on how to make this work? Thanks!!!
// 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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这似乎是您问题的根本原因:
要访问另一个类中的(非静态)方法,您需要此类的对象。在您的情况下,InputStream需要拥有一个ViewController对象,而不是成为一个ViewController对象。 (同样,ViewController 不应该是 JFrame,而是有一个 - 尽管这不会产生问题。)
如果您更改此设置,则不会获取你的构造函数循环。
This seems to be the root cause of your problem:
To access (non-static) methods in another class, you need an object of this class. In your case, the InputStream would need to have a ViewController object, not to be a ViewController object. (On the same lines, the ViewController should not be a JFrame, but have one - although this does not give problems here.)
If you change this, you don't get your constructor-loop.
你是说InputScreen扩展了ViewController吗?这看起来像是构造函数中的无限递归循环。而且,
什么也不做。您创建一个新的InputScreen,将其设置为变量home,一旦构造函数完成,它就会立即被GCed。
Are you saying that InputScreen extends ViewController? That seems like it would be an infinite recursive loop right there in the constructor. Also,
doesn't do anything. You create a new InputScreen set it to the variable home, which promptly gets GCed as soon as the constructor finishes.
简短回答:组合优于继承。 针对接口进行编程。 最小权限原则。 角色接口。
我建议您在阅读我的文章后对它们进行谷歌搜索;)
一方面,您不需要
InputStream
从ViewController
继承为VieController.doSaveAsXML ()
是公开的。即使它具有 private|protected|package 可见性,我们也不应该仅使用继承来访问我们不可见的其他类上的方法。继承用于继承、细化或扩展行为,而不是用于访问方法。
您始终可以将控制器作为参数类型传递给输入流。如果您的输入流需要访问控制器中的所有方法,请按原样传递控制器(或者让控制器实现一个包含其中所有方法的接口。)
首先要注意的重要事情是您的 < code>InputStream 并不真正需要访问控制器。它只需要访问可以执行
文件打开
功能的东西 - 它需要一个文件打开器
。需要注意的第二件重要事情是控制器(通常)也不需要知道如何打开文件。控制器通常是组织者或编排者(因为缺乏更好的词。)因此,它不需要是文件打开器(或实现文件打开逻辑本身。)控制器只需要对 aa
的引用文件打开器
。就像输入流
一样,控制器
只需将文件打开逻辑
委托给文件打开器
即可。换句话说:
访问文件打开器
可以访问文件打开器
输入流,因此,它需要
在期间将文件打开器传递给它
初始化
本身需要接收,
实例化或配置为
文件打开器本身。
流和控制器,
文件打开器应该是
接口(可以实现
通过 xml 文件打开器或任何打开器
无论
java 伪代码:
您是否一直让一切都针对接口处理程序工作,这是我们必须对每个项目做出的设计决策。但这种方法(或受其启发的方法)通常是可行的方法。通过这种方式(但并非不可能)提出循环依赖关系要困难得多,并且当它们确实发生时,它们是配置问题,而不是对象模型的内在问题。
希望有帮助。
Short answers: Composition over inheritance. Program against interfaces. Principle of Least Privilege. Role interfaces.
I'd suggest you do a google on them after reading my post ;)
For one thing, you do not need
InputStream
to inherit fromViewController
asVieController.doSaveAsXML()
is public.Even if it had private|protected|package visibility, we should not use inheritance only to access a method on some other class that is not visible to us. Inheritance is for inheriting, refining or extending behavior, not for accessing methods.
You can always pass the controller as an argument type to your input stream. If your input stream needs to access all methods in the controller, pass the controller as is (or have the controller implement an interface with all the methods in it.)
First important thing to notice is that your
InputStream
doesn't really need access to a controller. It only need access to something that can dofile opening
functions for it - it needs afile opener
.Second important thing to notice is that the controller (typically) doesn't need to know how to open files either. A controller is typically an organizer or orchestrator (for lack of a better word.) As such, it doesn't need to be a file opener (or implement file opening logic itself.) The controller just needs a reference to a a
file opener
. Just like theinput stream
, thecontroller
needs to simply delegatefile opening logic
to afile opener
.In other words:
access to a file opener
have access to a file opener
input stream, and so, it needs to
pass a file opener to it during
initialization
itself needs to receive,
instantiates or be configured with a
file opener itself.
both the stream and the controller,
the file opener should be an
interface (which can be implemented
by a xml file opener or any opener
for that matter.)
java pseudocode:
Whether you go all the way making everything working against interface handlers, that's a design decision that we have to make with every project. But this approach (or something inspired by it) is typically the way to go. It is much harder this way (but not impossible) to come up with cyclical dependencies, and when they do occur, they are a matter of configuration, and not of an intrinsic problem with you object model.
Hope it helps.