Why is State
declared as generic ? I dont see any specific value by doing that. If all you want to achieve is to be able to return concrete State
s from subclases , you can as well do this way :
abstract class State {
public abstract Set<? extends State> findNeighbors();
}
and then your sub states as :
class PuzzleState extends State {
@Override
public Set<PuzzleState> findNeighbors() {
Set<PuzzleState> set = new HashSet<PuzzleState>();
return set;
}
}
and
class QueensState extends State {
@Override
public Set<QueensState> findNeighbors() {
Set<QueensState> set = new HashSet<QueensState>();
return set;
}
}
EDIT after OPs first comment :
I have classes for displaying which need to know whether it is a state of Puzzle or the state of Queen
If your processing logic depends upon the knowledge of concrete types and cannot work polymorphically based on the abstract type - then thats most likely a design issue/smell if you want to stick to SOLID design principles.
You can think of refactoring the parts of your code that display the particular state like this :
In each concrete State
( ie PuzzleState
and QueenState
here ) have the logic of returning an interface StateImage
and then in the part of gui where you want to render your states' visual form - use interface ImageRenderer
abstract class State implements StateDisplayable{
public abstract Set<? extends State> findNeighbors();
}
class PuzzleState extends State {
@Override
public Set<PuzzleState> findNeighbors() {
Set<PuzzleState> set = new HashSet<PuzzleState>();
return set;
}
public Image getImage(){
return new PuzzleStateImage(); // implement this for Puzzle !!
}
}
class QueensState extends State {
@Override
public Set<QueensState> findNeighbors() {
Set<QueensState> set = new HashSet<QueensState>();
return set;
}
public Image getImage(){
return new QueenStateImage(); // implement this for QueenState!!
}
}
abstract class Image {
abstract void draw();
}
class PuzzleStateImage extends Image {
void draw() {
// knows what/how to render PuzzleState for a visual component
}
}
class QueenStateImage extends Image {
void draw() {
// knows what/how to render QueenStateImage for a visual component
}
}
interface StateDisplayable {
Image getImage();
}
interface StateRenderer {
void draw(Image state);
}
and then in GUI code
void display(){
StateRenderer renderer = null ; // instantiate
Set<? extends State> states = null; // get your states here ( this is a mix of Puzzle and Queen states - but you dont care about the concrete type )
for(StateDisplayable state : states){
Image stateImage = state.getImage(); // this could be Puzzle or Queen stateImage
renderer.draw(stateImage);
}
}