Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果对象引用是在类获取参数之后实例化的,那么如何使用对象引用作为参数?_Java_Class_Object_Constructor_Arguments - Fatal编程技术网

Java 如果对象引用是在类获取参数之后实例化的,那么如何使用对象引用作为参数?

Java 如果对象引用是在类获取参数之后实例化的,那么如何使用对象引用作为参数?,java,class,object,constructor,arguments,Java,Class,Object,Constructor,Arguments,所以我有这个代码: package com.erikbalen.game.rpg; import com.erikbalen.platform.*; import javax.swing.JFrame; public class World extends Engine { public static void main(String[] args) { Gui display = new Gui(/*takes a Player argument so i

所以我有这个代码:

package com.erikbalen.game.rpg;
import com.erikbalen.platform.*;
import javax.swing.JFrame;

public class World extends Engine {

    public static void main(String[] args) {        

    Gui display = new Gui(/*takes a Player argument so i can get certain variables*/);
    display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    display.setSize(300,220);
    display.setVisible(true);

    Player player1 = new Dps("ebalen", display);
    Player player2 = new Healer("frankypanky", display);

    }

}

package com.erikbalen.game.rpg;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Gui extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = -384241835772507459L;
    private JLabel playerInfo;
    private JTextField textField;
    private final static String newline = "\n";
    private JTextArea feed;
    private JScrollPane scrollPane;
    private Player player;

    public Gui(Player currentPlayer) {
        super("Erik's RPG");
        this.player = currentPlayer;
        setLayout(new FlowLayout());

        playerInfo = new JLabel("<html>Health = " + currentPlayer.getHealth() + " | " + "Mana = " + currentPlayer.getMana() + "</html>");

        playerInfo.setBorder(BorderFactory.createTitledBorder(currentPlayer.getName()));

        textField = new JTextField(20);

        textField.addActionListener(this);

        feed = new JTextArea(5, 20);
        scrollPane = new JScrollPane(feed);
        feed.setEditable(false);

        add(playerInfo);
        add(feed);
        add(textField);
        add(scrollPane);

    }

    public void actionPerformed(ActionEvent textBox) {
         String text = textField.getText();
         this.player.chat(text);

    }

    public void printText(String text) {
        feed.append(text + "\n");
        feed.setCaretPosition(feed.getDocument().getLength());
    }

}
package com.erikbalen.game.rpg;
导入com.erikbalen.platform.*;
导入javax.swing.JFrame;
公共类世界扩展引擎{
公共静态void main(字符串[]args){
Gui display=newgui(/*接受一个Player参数,这样我就可以得到某些变量*/);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
显示。设置大小(300220);
display.setVisible(true);
Player player1=新Dps(“ebalen”,显示);
player2=新治疗者(“弗兰基银行”,显示);
}
}
包com.erikbalen.game.rpg;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.*;
公共类Gui扩展JFrame实现ActionListener{
/**
* 
*/
私有静态最终长serialVersionUID=-384241835772507459L;
私人JLabel playerInfo;
私有JTextField textField;
私有最终静态字符串换行符=“\n”;
私人区域馈送;
私有JScrollPane滚动窗格;
私人玩家;
公共Gui(播放器当前播放器){
超级(“埃里克的RPG”);
this.player=currentPlayer;
setLayout(新的FlowLayout());
playerInfo=new JLabel(“Health=“+currentPlayer.getHealth()+”|“+”Mana=“+currentPlayer.getMana()+”);
playerInfo.setBorder(BorderFactory.createTitledBorder(currentPlayer.getName());
textField=新的JTextField(20);
textField.addActionListener(这个);
feed=新的JTextArea(5,20);
scrollPane=新的JScrollPane(提要);
feed.setEditable(false);
添加(playerInfo);
添加(饲料);
添加(文本字段);
添加(滚动窗格);
}
已执行的公共无效操作(操作事件文本框){
String text=textField.getText();
this.player.chat(文本);
}
公共无效打印文本(字符串文本){
feed.append(文本+“\n”);
feed.setCaretPosition(feed.getDocument().getLength());
}
}

我的问题是类Gui将播放器作为参数,而播放器将Gui作为参数。如何让两个对象都将彼此作为参数?请随时告诉我我的代码是否效率低下。

尝试提供
Gui
类方法来更新向用户显示的内容。使指导代码(
main()
例如)负责在事件发生时用正确的信息更新
Gui


无论是
Gui
还是
Player
都不应将彼此视为构造函数参数-
Gui
只应负责显示告知它的信息,而
Player
只应是游戏的逻辑表示。事件驱动的功能应该为指导代码保留。

理想情况下,您应该尝试打破循环依赖,否则,您可以:

  • 创建GUI,通过传入GUI来创建播放器,然后将播放器添加到GUI
  • 创建播放器,通过传入播放器创建GUI,然后为播放器设置GUI
  • 在播放器构造函数中创建GUI:

    Player(String name)
    {
        GUI gui = new GUi(this);
        ...
    }
    
所有这些都是不理想的:

  • 您可能希望您的类是不可变的,这使得前两个选项很糟糕
  • 在构造函数完成执行之前发布
    this
    引用存在各种问题,包括线程安全和内存模型方面的问题,以及可能允许
    GUI
    构造函数在
    Player
    对象完全初始化之前回调该对象的问题

这可以追溯到“尝试打破依赖”——但如果这真的不可能,我可能会支持第一种选择,而不知道其他任何事情。将玩家添加到游戏中是有意义的——我认为,在游戏结束后为玩家设置GUI是没有意义的。

你陷入了我们称之为循环依赖的状态。这几乎每次都是糟糕设计的结果

仍然有解决方案,但并没有真正的解决方案。为了达到优雅的效果,你应该重新考虑你的设计。
GUI真的需要播放器吗?也许你可以创建一个方法来设置播放器。如果不可能,你也可以在球员中创造一个二传手。您无法在构建时同时设置这两个参数。

为什么
Gui
Player
作为构造函数参数?我认为这可能是个糟糕的设计。请显示您的
Gui
代码。因为Gui显示了一些玩家的信息,我不知道如何让它访问玩家变量。您可以使用
setPlayer
方法,而不是使用构造函数参数。+1,我会强调更多关于尝试打破依赖关系的内容。我不想发生
堆栈溢出错误
(讽刺)。此外,调试循环依赖性并不是一个简单的大开眼界的事情,如果不打破一些牙齿和骨头。你能解释一下我将如何打破依赖性吗?@ebalen:很难说不知道为什么会有循环依赖性。GUI构造函数将单个播放器作为“当前”播放器似乎很奇怪。您是否考虑过在当前播放机每次更改时调用setCurrentPlayer方法?