2

Well I've run into a predicament...

Ok I have 4 classes, 2 I cannot edit,

  • StateBasedGame (Not Editable)
  • GameState (Not Editable)
  • Game extends StateBasedGame
  • EnhancedGameState extends GameState

The StateBasedGame contains the public method void addState(GameState state), however for the class Game I want to make this method accept only an EnhancedGameState, or create a new method, as it contains the method isOrderable() which I need to call.

This won't work as I will produce a compiler error.

public void addEnhancedState(EnhanchedGameState state){
    addState(state);
    //Do Other Logic    
}

@Override
private void addState(GameState state) { 
    super.addState(state);
}

There may not be an answer, but how would you go about doing this.

EDIT: I don't want to know why this isn't working. I want to know how to do this.

Thanks in advance,

– Curlip

Curlip
  • 395
  • 1
  • 3
  • 15
  • 1
    What kind of compiler error do you got? – wawek Aug 27 '15 at 09:57
  • @wawek I get the compiler error "Cannot reduce the visibility of the inherited method from StateBasedGame" (http://stackoverflow.com/questions/1600667/why-cant-you-reduce-the-visibility-of-a-method-in-a-java-subclass) – Curlip Aug 27 '15 at 09:59
  • 1
    `if (! (state instanceof EnhancedGameState)) ...`. Since you cannot change the base class, curiously recurring generics aren't an option ... – dhke Aug 27 '15 at 10:05
  • @dhke That thought hadn't even crossed my mind... – Curlip Aug 27 '15 at 10:06

1 Answers1

0

You are overriding a public parent method with a private child method.

Fix it this way:

@Override
public void addState(GameState state) { 
    super.addState(state);
}

And BTW, this piece of code is redundant since you can just call the parent addState() directly.

UPDATED: you could make it 'unusable' in the following somewhat ugly manner:

@Override
@Deprecated
public void addState(GameState state) { 
    throw new UnsupportedOperationException("explain why");
}

public void addState(EnhanchedGameState state) { 
    ... new implementation
}
S. Pauk
  • 5,208
  • 4
  • 31
  • 41
  • I know that this is why it isn't working, however this isn't what I want, I want this method to be unusable. – Curlip Aug 27 '15 at 10:03
  • Well I guess I could do that... However @dhke's solution seems to fit the situation. However, Thankyou for your time. – Curlip Aug 27 '15 at 10:09
  • I've got an impression that you would like to change the signature so that a class user sees it right away. If using an old signature is OK then you could go with a solution proposed by @dhke. – S. Pauk Aug 27 '15 at 10:12
  • Improved the answer with a @Deprecated annotation – S. Pauk Aug 27 '15 at 10:13
  • Well I would like to change the signature simply for friendliness, however I don't think it is possible. I don't know about using the Exception, it may be interpreted as as crash by the end-user, if not handled correctly. – Curlip Aug 27 '15 at 10:20
  • I'd keep the `@Deprecated`, and forward to the `EnhancedGameState` version after the `instanceof` check and fail otherwise. This makes it work even if someone calls the deprecated method with the proper object and at the same time encourages people to use the new type. – dhke Aug 27 '15 at 10:29
  • @dhke with the implementation above you cannot call a deprecated method with a proper object cause you will right away fall into the overloaded new version. The deprecated one will only be invoked if an object is of `GameState` type (which is an invalid situation as far as I understood from the spex) – S. Pauk Aug 27 '15 at 11:03
  • @SergeyPauk It should not happen, but the overload resolution is based on runtime type. So if somebody has `GameState state = new EnhancedGameState(); game.addState(state)` somewhere, there will be a runtime error (plus the deprecation warning). It's possible to avoid the runtime error, but which one is *right* looks like a design choice too me. – dhke Aug 27 '15 at 11:34
  • @dhke @Sergery Pauk Would I be able to create two `addState` Methods one with a GameState parameter and one with an EnhancedGameState. Doing the Enhanced logic in the EnhancedGameState method before passing it to the GameState method to do the common logic. – Curlip Aug 28 '15 at 10:48
  • @curlip that is technically possible but could you explain what are you trying to achieve in this case? – S. Pauk Aug 28 '15 at 18:32
  • Both classes will have some common logic, adding them to a list, however the `EnhancedGameState` has some added logic to it, adding its id to a second list. – Curlip Aug 28 '15 at 21:40