【问题标题】:Java - Extended static class of a non-static classJava - 非静态类的扩展静态类
【发布时间】:2011-06-12 04:45:50
【问题描述】:

我有一个“字符”类,字符是非静态的。我希望我的播放器类扩展 Character,但也是静态的。

我基本上希望所有其他对象和类都能够访问播放器,而无需创建和传递播放器实例。

实现这一目标的最佳理由是什么?

【问题讨论】:

  • 将类命名为与 java.lang.Character 类相同的坏主意
  • 非常正确,我正在缩小范围,但我想我可能会改变它。
  • 你确定你理解在处理类时“静态”是什么意思吗?顶级类不能声明为静态的,也不能声明为非静态的。
  • 正确,我的意思是,我在角色中有非静态方法,我需要在播放器中保持静态。
  • 听起来您当前的处理方法是错误的,但如果没有更多关于实际目标的信息,我不确定我们是否可以推荐更好的方法。

标签: java class object static


【解决方案1】:

我能想到的唯一好方法实际上不是扩展而是包装器:

class Player {
    private final static Charachter me = new Character();

    public static doSomething(){ me.doSomething(); }
}

当然你也可以扩展 AND wrap:

class Player extends Character {

    private final static Player me = new Player();

    // if you don't want anyone creating player objects
    // make the constructor private:
    private Player(){ super(); }

    public void doSomething(){
        // stuff
    }

    public static void staticDoSomething(){ me.doSomething(); }
}

或者,实际上,由于您的目标只是保证只有一个玩家对象,您可以忘记将方法设置为静态,而是隐藏构造函数:

class Player extends Character {

    private static Player thePlayer = null;

    public static Player getPlayer(){
        if( thePlayer == null ){
            // Create the player
            thePlayer = new Player();
        }
        // There is a valid player object, so return it.
        return thePlayer;
    }

    // hide the constructor(s) by making them private:

    private Player(){ super(); }
}

这确保了获得Player 的唯一方法是调用Player.getPlayer(),并且它始终为您提供相同的对象(您永远不会创建多个)。

【讨论】:

  • 在商业中,我们称之为“优先组合胜于继承”;)
  • 嘿,我学到了一个新名词。还添加了非组合解决方案。
  • ...我没有阅读 Mark Peters 的解决方案,但第三个选项几乎是它的副本。
  • 好的,新的解决方案看起来是最好的。我从来没有想过要那样做。谢谢!
【解决方案2】:

真的,您似乎只想要一个全局变量。这通常通过单例模式来完成:

public class Player extends Character {
    private static final Player humanPlayer = new Player();

    private Player() {
    }

    public static Player getHuman() {
        return humanPlayer;
    }

    //...
}

//...
Player.getHuman().move(2);

Player 中的这些方法几乎不需要是静态的。你为了一点点的方便而牺牲了好的设计(反正以后可能会咬你)。

就我个人而言,大约 95% 的时间我更喜欢依赖注入而不是全局状态。当某个方法需要访问播放器时,将其传入。这将使您更轻松地测试代码,并使您的代码更有利于更改。

【讨论】:

  • 那些需要访问播放器的类/对象呢?比如我的 GUI 需要访问它,那我真的应该直接传入吗?
  • @Paramount 好东西——你不需要传入它,他们可以通过Player.getHuman()获取玩家对象
  • 啊好吧,你们之间可以@trutheality 我想我现在明白了。谢谢
猜你喜欢
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 2014-01-17
相关资源
最近更新 更多