繁体   English   中英

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

[英]How to call methods of subclass from superclass object

我正在编写具有许多不同类的国际象棋Java程序。 例如,我有一个Chess_Piece超类,从这个我有很多子类,例如RookKing等。

我在每个子类中都有一个isValidMove()方法(因为每个片段都以特定的方式移动)。 有没有一种方法可以在Chess_Piece对象上调用isValidMove() ,编译器将在其中照顾要调用的特定子类的isValidMove()

本质上,我从用户那里获取输入,然后将Chess_Piece移动到该位置。 如果没有复杂的ifs系统(即if Chess_Piece.toString=="Rook"if Chess_Piece.toString=="Bishop"等),我的程序将无法准确判断出哪个子类Piece驻留在该位置。 有任何想法吗?

这正是多态性的含义。

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

}

这是Java(以及所有合理的OO语言)的默认行为。

您是否有不按这种方式运行的代码?

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

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

如果使用一些代码对此进行测试,您将看到Java表现出了您想要的方式:

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

产生: King

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

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

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

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

这样,您可以确保每个扩展Chess_Piece的类都具有isValidMove()方法,否则将不会编译。

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

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

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

通过多态性,您可以编写

piece.isValidMove();

而且对所有人都适用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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