简体   繁体   中英

Java: get rid of if else by using generic type

in my code, I've used many if-else statements. I've learned that if-else and switch statements are not an elegant way to code, is there a good way to refactor the following code?

Wall, Trap, Door and Floor are subclass of Tile

    public class Player{
    ...
        public void move(DIR dir) throws Exception {
            Position nextPos = checkMove(dir);
            Tile nextTile = TileManager.getTileType(nextPos.getSeq());
            if (nextTile instanceof Floor) {
                walk();
            } else if (nextTile instanceof Wall) {
                block();
            } else if (nextTile instanceof Trap) {
                trap();
            } else if (nextTile instanceof Door) {
                unlock();
            }
        }
        public void walk(){
            ...
        }
        public void block(){
            ...
        }
        public void trap(){
            ...
        }
    ...
    }

I've tried to solve this by using method overload

public void move1(DIR dir) throws Exception {
    Position nextPos = checkMove(dir);
    System.out.println(nextPos);
    Tile nextTile = TileManager.getTileType(nextPos.getSeq());
    moveTo(nextTile);
} 
public void moveTo(Floor next) throws Exception {
    walk();
}
public void moveTo(Wall next) throws Exception {
    block();
}
...

and there is a compilation error

The method move1(Floor) in the type Player is not applicable for the arguments (Tile)

I've read some post that suggest generic type might be a solution, but i dont know how to implement it.

I've learned that if-else and switch statements are not an elegant way to code, is there a good way to refactor the following code?

One potential solution is to add an abstract method to Tile , let's call it action() . (Feel free to come up with a better name.) Then you can do nextTile.action() without the if statement. Then rename Floor.walk() to Floor.action() and similarly with the other specialized methods for each Tile subclass. This has the added benefit that you can create new Tile subclasses and move() will be able to handle them without any changes.

Well, the style depends on the language. You may mix Java and Kotlin in a single project: https://kotlinlang.org/docs/tutorials/mixing-java-kotlin-intellij.html

You may create a Kotlin file in your existing Java project with something like this (not tested):

when (nextTile) {
   is Floor -> walk()
   is Wall -> block()
   is Trap -> Trap()
   is Door -> unlock()
   else -> throw IllegalArgumentException("Unknown expression")
}

Have a look at

https://try.kotlinlang.org/#/Kotlin%20Koans/Introduction/Smart%20casts/Task.kt

https://kotlinlang.org/docs/reference/typecasts.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM