Java - 在自身内部使用枚举值

时间:2014-09-26 12:02:09

标签: java android enums libgdx

我们正在使用libgdx为Android设备制作游戏原型。对于屏幕管理,我们使用带有屏幕名称的枚举来获取ScreenManager类的抽象层。所以你可以做这样的事情来显示一个新的屏幕并隐藏旧屏幕:ScreenManager.getInstance().show( Screens.LOGIN );

现在我们要使用设备的后退按钮跳回屏幕或退出应用程序。所以我们想在每个枚举值中创建一个字段来声明parentScreen并在按下后退按钮时使用它。不幸的是,它本身不能使用enum自己的字段,我们在Cannot refer to the static enum field Screens.LOGIN within an initializer上收到以下错误:protected Screens parentScreen = Screens.LOGIN;。也许任何人都知道如何解决这个问题。

这是实际的枚举:

/**
 * Used to hide actual implementations of Screen interface and expose only "pointer objects".
 * All of them are declared with package-private class modifier.
 */
public enum Screens {

SPLASH {
    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new SplashScreen( game );
    }
},

LOGIN {
    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new LoginScreen( game );
    }
},

GAME {
    protected Screens parentScreen = Screens.LOGIN;

    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new GameScreen( game );
    }
},

CREDITS {
    protected Screens parentScreen = Screens.LOGIN;

    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new CreditsScreen( game );
    }
};

protected Screens parentScreen = null;

/** Every enum member musts override this method and it will be visible only inside the package */
protected abstract Screen getScreenInstance( MyGdxGame game );
}

此功能应显示父屏幕:

/**
 * Execute when the user clicks the back button
 * Default called by the AbstractScreen Class
 */
public void backButton() {
    this.show( this.currentScreen.parentScreen );
}

提前感谢您的建议!

2 个答案:

答案 0 :(得分:2)

有多种可能性。我最喜欢的是使用构造函数,因为它的文本较少,但更容易理解:

public enum Screens {

SPLASH(Screens.LOGIN) {
    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new SplashScreen( game );
    }
},

LOGIN(null) {//...}

;//this semi-colon is expected after the enum values

private final Screens parentScreen;

Screens(Screens parent){//Constructor
    parentScreen = parent;
}

public Screens getParentScreen(){
    return parentScreen;
}

protected abstract Screen getScreenInstance( MyGdxGame game );

另一个解决方案是声明一个抽象方法getParentScreen():

public enum Screens {

SPLASH {
    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new SplashScreen( game );
    }
    @Override
    protected Screen getParentScreen() {
        return Screens.LOGIN;
    }
},
//...
;

protected abstract Screen getScreenInstance( MyGdxGame game );
protected abstract Screen getParentScreen();

答案 1 :(得分:1)

你可以试试这个:

/**
 * Used to hide actual implementations of Screen interface and expose only "pointer objects".
 * All of them are declared with package-private class modifier.
 */
public enum Screens {

SPLASH {
    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new SplashScreen( game );
    }
},

LOGIN {
    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new LoginScreen( game );
     }
},

GAME {
    @Override
    protected Screen getParentScreen() {
       return Screens.LOGIN;
    } 

    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new GameScreen( game );
    }
},

CREDITS {

    @Override
    protected Screen getParentScreen() {
       return Screens.LOGIN;
    } 


    @Override
    protected Screen getScreenInstance( MyGdxGame game ) {
        return new CreditsScreen( game );
    }
};

protected Screen getParentScreen() {
    return null;
} 

/** Every enum member musts override this method and it will be visible only inside the package */
protected abstract Screen getScreenInstance( MyGdxGame game );
}

通过使用方法(而不是字段),您可以克服限制。

注意 此外,做一些事情:

public enum X {
  VALUE1 {
     protected String fieldYYY = ...;
  }

  protected String fieldYYY = ...;
}

不是一件好事。当编译枚举时,它们大致转换为具有子类X.VALUE1,X.VALUE2,X.VALUEN的抽象超类X ...如果在超类(X)中声明一个字段,然后在子类中再次声明它你并没有真正覆盖它,但你最终得到了2个字段,具有相同的名称......第一个(X中的一个,超类)被范围隐藏......但它就在那里!如果这些字段是可变的 - 不是枚举的情况 - 你可能会释​​放混乱(某些代码引用你的超类中的那些,其他代码就是你拥有的代码)!