I'm working on program/game where I have static utility class with params.
class ParamsGeneral {
public static final int H_FACTOR = 100;
public static int MAX_SCORE = 1000;
...
}
then I need to override this values in some specific cases, for example playing on map with limited score. So I did following:
class ParamsLimited extends ParamsGeneral {
public static int MAX_SCORE = 500;
// other params stay same
}
And the intended usage is following:
class Player {
ParamsGeneral par;
public Player() {
if(onLimitedMap()){
par = new ParamLimited();
}
}
public boolean isWinner() {
if(this.score == par.MAX_SCORE) {
return true;
}
return false;
}
}
I haven't actually tested this code, because IDE is complaining about calling static field through instance and also about field hiding. I clearly see that this code is stinks, so is there a way to achieve this or do I have to write each param class separately?
PS: I know I shoud make the default class abstract and use getters, I'm just curious if there is a way to make the values accesible statically.
You cannot override static members - in Java, neither methods nor fields could be overriden. However, in this case it does not look like you need to do any of that: since you have an instance of ParamsGeneral
in the par
variable, a non-static method would do what you need with the regular override.
class ParamsGeneral {
public int getMaxScore() {
return 1000;
}
}
class ParamsLimited extends ParamsGeneral {
@Override public int getMaxScore() {
return 500;
}
}
...
public boolean isWinner() {
// You do not need an "if" statement, because
// the == operator already gives you a boolean:
return this.score == par.getMaxScore();
}
I wouldn't use subclassing for a general game vs a limited game. I would use an enumeration, like:
public enum Scores {
GENERAL (1000),
LIMITED (500),
UNLIMITED (Integer.MAX_INT);
private int score;
private Scores(int score) { this.score = score; }
public int getScore() { return score; }
}
Then, when constructing a game, you can do:
Params generalParams = new Params(Scores.GENERAL);
Params limitedParams = new Params(Scores.LIMITED);
And so forth.
Doing it this way allows you to change the nature of your game while keeping your values centralized. Imagine if for every type of parameter you think of you have to create a new class. It could get very complicated, you could have hundreds of classes!
Simplest solution is to do this:
class ParamsGeneral {
public static final int H_FACTOR = 100;
public static final int MAX_SCORE = 1000;
public static final int MAX_SCORE_LIMITED = 500;
...
}
class Player {
int maxScore;
public Player() {
if(onLimitedMap()){
maxScore = ParamsGeneral.MAX_SCORE_LIMITED;
}
else {
maxScore = ParamsGeneral.MAX_SCORE;
}
}
public boolean isWinner() {
if(this.score == this.maxScore) {
return true;
}
return false;
}
}
No need to have an instance of ParamsGeneral, it is just a collection of static definitions for your game.
Have MAX_SCORE
be private static with public static getters; then you can call ParamsGeneral.getMaxScore
and ParamsLimited.getMaxScore
and you'll get 1000 and 500 respectively