使用已检查的异常重写方法



我有两个类,A和B,其中B扩展了A。我遇到了一个问题,B引入了一个附加功能,该功能附带了一个异常ExceptionC,该异常不以任何形式应用于A,但除非A指定它为throws ExceptionC,否则它不会编译。我知道这是故意的(因为利斯科夫替代原则)。我的问题有两个:

  1. 利斯科夫替代原则背后的原因是什么?如果B扩展了A,难道它不应该添加更多的功能,从而添加例外吗
  2. 有什么更好的方法可以做到这一点?在超类中添加一个不适用的异常感觉是错误的

具体情况:

我正在用Java编写一个终极Tic-Tac-Toe的实现。基本上取一个井字网格,并用井字网格填充,如下所示:

| | # | | # | | 
| | # | | # | | 
| | # | | # | | 
#################
| | # | | # | | 
| | # | | # | | 
| | # | | # | | 
#################
| | # | | # | | 
| | # | | # | | 
| | # | | # | |

你从中心开始,X在这个网格中的任何位置,O都在对应于较大网格的网格中,所以在两次移动后,它可能看起来像这样:

| |O# | | # | | 
| | # | | # | | 
| | # | | # | | 
#################
| | #X| | # | | 
| | # | | # | | 
| | # | | # | | 
#################
| | # | | # | | 
| | # | | # | | 
| | # | | # | |

如果目标网格已满或已经获胜,下一个人可以选择进入哪个网格。

我有两个普通类、两个异常类和一个接口。

  • TTTBoard实现Board
  • UltimateTTTB板扩展TTT板实现板
  • TTTBoard.move抛出LocationTakeException
  • UltimateTTTBoard.move引发LocationTakeException、TargetBoardFullException

请注意,在标准井字游戏中,只有一块板,因此TargetBoardFullException完全不适用。

我做错了吗?我不应该对此使用例外吗?

以下代码显示了Java不允许更改合同的原因:

class A {
public void method() {
// do something
}
}
class B extends A {
public void method() throws IOException {  // <- compile error here
// do something and throw and exception
}
}
class App {
public static void main(String[] args) {
A a = new B();
a.method();  // to try or not to try, that's the question now.
}
}

当然,它不会编译。但是,如果是这样的话,我们是否必须在主方法中捕获IOException(因为它是B实例)(因为我们在接口上调用该方法)?

最新更新