如果对象引用是在接受参数的类之后实例化的,如何使用对象引用作为参数?

发布于 2024-12-04 09:43:06 字数 2119 浏览 0 评论 0原文

所以我有这样的代码:

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());
    }

}

我的问题是类 Gui 将 Player 作为参数,而 Player 将 Gui 作为参数。如何让两个对象互相作为参数?如果我的代码效率低下,请随时告诉我。

So I have this code:

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());
    }

}

My problem is that class Gui takes a Player as an argument and Player takes Gui as an argument. How do I let both objects take each other as arguments? Feel free to tell me if my code is inefficient.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苄①跕圉湢 2024-12-11 09:43:06

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

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

    玩家(字符串名称)
    {
        GUI gui = 新 GUI(this);
        ...
    }
    

所有这些都不是理想的:

  • 您可能希望您的类是不可变的,这使得前两个选项变得令人讨厌
  • 发布 this 在构造函数完成执行之前的引用存在各种问题,无论是在线程安全性还是内存模型方面,以及可能允许 GUI 构造函数回调到 Player 对象在完全初始化之前。

这可以追溯到“尝试打破依赖性” - 但如果这真的不可能,我可能会倾向于第一个选项,而不知道其他任何事情。能够将玩家添加到游戏中是有意义的 - 在事后为玩家设置 GUI 就没有意义了,IMO。

Well, ideally you should try to break the circular dependency, but otherwise, you could:

  • Create the GUI, create the players by passing in the GUI, then add the players to the GUI
  • Create the players, create the GUI by passing in the players, then set the GUI for the players
  • Create the GUI within the player constructor:

    Player(String name)
    {
        GUI gui = new GUi(this);
        ...
    }
    

All of these are non-ideal:

  • You may well want your classes to be immutable, which makes the first two options nasty
  • Publishing the this reference before your constructor has finished executing has various issues, both in terms of thread safety and the memory model, as well as potentially allowing the GUI constructor to call back to the Player object before it's fully initialized.

This goes back to "try to break the dependency" - but if that's really impossible, I would probably favour the first option, without knowing anything else. It makes sense to be able to add players to a game - it makes less sense to set the GUI for a player after the fact, IMO.

一曲琵琶半遮面シ 2024-12-11 09:43:06

你陷入了我们所说的循环依赖。这几乎每次都是糟糕设计的结果。

仍然有解决方案,但并不是非常漂亮。为了以优雅的方式,您应该重新考虑您的设计。
GUI 真的需要播放器吗?也许您可以创建一个稍后设置播放器的方法。如果不可能,您还可以在播放器中创建一个 setter。您将无法在构建时同时设置两者。

Your stuck in what we call a circular dependency. This is almost everytime the result of a bad design.

There are still solutions, but there are not really pretty. For an elegant way, you should rethink your design.
Does the GUI really need the player ? Maybe you could create a method to set the player later on. If it's not possible, you could also create a setter in the player. You won't be able to set both at construction time.

柒七 2024-12-11 09:43:06

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

GuiPlayer 都不必将彼此作为构造函数参数 - Gui 应该只负责显示它被告知的信息,并且 < code>Player 应该只是游戏棋子的逻辑表示。事件驱动的功能应该为指导代码保留。

Try giving the Gui class methods for updating what is displayed to the user/users. Make the directing code (main() for example) responsible for updating the Gui with the right information as events happen.

Neither Gui nor Player should have to take each other as constructor arguments - Gui should only be responsible for displaying information it is told to, and Player should only be a logical representation of a game piece. Event-driven functionality should be reserved for the directing code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文