简体   繁体   中英

How to call methods of subclass from superclass object

I am writing a java program for a chess game with a lot of different classes. For instance, I have a Chess_Piece superclass, and from this I have many subclasses, like a Rook , King , etc.,

I have a isValidMove() method in each subclass (as each piece moves in a particular manner). Is there a way to call isValidMove() on a Chess_Piece object, where the compiler will take care of which particular subclass's isValidMove() to call?

Essentially, I take input from a user and then move the Chess_Piece at that location. My program cannot tell exactly which subclass Piece resides at that location without an elaborate system of ifs (ie if Chess_Piece.toString=="Rook" , if Chess_Piece.toString=="Bishop" etc). Any ideas?

This is exactly what polymorphism is about.

// The whole class must be declared abstract if it contains at least one abstract method. 
// Abstract classes themselves can't be instantiated, but their non-abstract subclasses can be. 
public abstract class Chess_Piece {

    // Declare the method as abstract. 
    // "Abstract" means that the implementation will be provided in subclasses.
    // Make it protected if not called from outside this class hierarchy. 
    // Declare arguments as needed.
    public abstract boolean isValidMove();

    // Your other methods. 
    // You may call `isValidMove()` in other methods. 

}

// King class provides implementation of all abstract methods, 
// and therefore the class isn't abstract. 
public class King extends Chess_Piece {

    @Override
    public boolean isValidMove() {
        // Implement method body as needed
        return true;
    }

}

This is the default behavior for Java (and for any sane OO language).

Do you have code that isn't behaving this way?

here is an example to show how classes might be set up

public class ChessPiece {
    public void isValidMove(){
        System.out.println("Super");
    }
}

public class King extends ChessPiece {
    public void isValidMove(){
        System.out.println("King");
    }
}

public class Queen extends ChessPiece {
    public void isValidMove(){
        System.out.println("Queen");
    }
}

if you test this with some code you'll see Java behaves the way you want already:

public static void main(String[] args) {
    ChessPiece king = new King();
    //king is declared to be a ChessPiece, but the value is a king.
    king.isValidMove();
}

Which produces: King

See more about this kind of behavior here: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

When calling a function on an object, it will look first at the class that created the object, then at its superclass, and so on up the inheritance tree. Therefore if you call Chess_Piece piece = new Rook() then piece.isValidMove() will call the Rook class's isValidMove method.

In your use case, I would recommend declaring an abstract function in Chess_Piece:

public class Chess_Piece {
  public abstract boolean isValidMove();
}

This way, you guarantee every class that extends Chess_Piece has a isValidMove() method or it won't compile.

Well, try this... You say Chess_Piece piece is input by user, so

if(piece instanceof Pawn){
// do Pawn thing
}
else if(piece instanceof Rook){
//do Rook thing
}
//and for all

But I recommend you to use polymorphism concept as given in other answers.

By polymorphism, you can write

piece.isValidMove();

and it works fine for all.

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