如果在获取参数的类之后实例化对象引用,我该如何使用它作为参数?

时间:2011-09-13 05:19:38

标签: 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 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作为参数。我如何让两个对象互相作为参数?如果我的代码效率低下,请随时告诉我。

3 个答案:

答案 0 :(得分:5)

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

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

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

所有这些都不理想:

  • 你可能希望你的课程是不可变的,这使得前两个选项变得讨厌
  • 在构造函数执行完毕之前发布this引用在线程安全性和内存模型方面存在各种问题,并且可能允许GUI构造函数回调{ {1}}对象在完全初始化之前。

这可以追溯到“试图打破依赖” - 但如果那个真的不可能,我会可能赞成第一个选项,而不知道其他什么。能够将玩家添加到游戏中是有意义的 - 在IMO之后为玩家设置GUI没有多大意义。

答案 1 :(得分:1)

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

GuiPlayer都不应该互相作为构造函数参数 - Gui应该只负责显示告知的信息,Player只应该是游戏片的逻辑表示。应为导向代码保留事件驱动的功能。

答案 2 :(得分:1)

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

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