如何从超类对象中调用子类的方法

时间:2016-02-15 19:32:39

标签: java oop

我正在为一个有很多不同类的国际象棋游戏编写一个java程序。例如,我有一个Chess_Piece超类,从中我有很多子类,如RookKing等,

我在每个子类中都有一个isValidMove()方法(因为每个部分都以特定的方式移动)。有没有办法在isValidMove()对象上调用Chess_Piece,编译器将负责调用哪个特定子类isValidMove()

基本上,我从用户那里获取输入,然后在该位置移动Chess_Piece。如果没有精心设计的ifs系统,我的程序无法确切地确定Piece位于哪个子类中(即 if Chess_Piece.toString=="Rook"if Chess_Piece.toString=="Bishop"等)。有什么想法吗?

4 个答案:

答案 0 :(得分:2)

这正是多态性的意义所在。

// 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;
    }

}

答案 1 :(得分:1)

这是Java(以及任何理智的OO语言)的默认行为。

你有没有这样做的代码吗?

这是一个显示如何设置类的示例

operator .

如果您使用某些代码对此进行测试,您会看到Java的行为方式已经符合您的要求:

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");
    }
}

哪个产生: 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(); }

在此处查看有关此类行为的更多信息: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

答案 2 :(得分:1)

在对象上调用函数时,它首先会查看创建该对象的类,然后是其超类,依此类推依赖继承树。因此,如果您致电Chess_Piece piece = new Rook(),则piece.isValidMove()将调用Rook类的isValidMove方法。

在您的用例中,我建议在Chess_Piece中声明一个抽象函数:

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

这样,您可以保证每个扩展Chess_Piece的类都有一个isValidMove()方法,或者它不会编译。

答案 3 :(得分:0)

好吧,试试吧...... 您说Chess_Piece piece是由用户输入的,所以

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

但我建议你使用其他答案中给出的多态概念。

通过多态,你可以写

piece.isValidMove();

它适用于所有人。