Java 使用选中的异常重写方法

Java 使用选中的异常重写方法,java,oop,inheritance,Java,Oop,Inheritance,我有两个类,A和B,其中B扩展了A。我遇到了一个问题,B引入了一个额外的功能,它附带了一个ExceptionExceptionC,它不以任何方式应用于A,但除非A指定抛出ExceptionC,否则它不会编译。我知道这是设计的,因为利斯科夫替换原理。我的问题有两个: Liskov替代原则背后的原因是什么?如果B扩展了A,它不应该添加更多的特性,从而添加异常吗? 有什么更好的方法可以做到这一点?在超类中添加不适用的异常感觉是错误的。 具体情况: 我正在用Java编写一个终极Tic-Tac-Toe的实

我有两个类,A和B,其中B扩展了A。我遇到了一个问题,B引入了一个额外的功能,它附带了一个ExceptionExceptionC,它不以任何方式应用于A,但除非A指定抛出ExceptionC,否则它不会编译。我知道这是设计的,因为利斯科夫替换原理。我的问题有两个:

Liskov替代原则背后的原因是什么?如果B扩展了A,它不应该添加更多的特性,从而添加异常吗? 有什么更好的方法可以做到这一点?在超类中添加不适用的异常感觉是错误的。 具体情况:

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

 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | |
 | |O# | | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | #X| | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | |
从中心开始,无论X在哪个网格中,O都在对应于大网格的网格中,所以在两次移动后,它可能会如下所示:

 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | |
 | |O# | | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | #X| | # | | 
 | | # | | # | | 
 | | # | | # | | 
#################
 | | # | | # | | 
 | | # | | # | | 
 | | # | | # | |
如果目标网格已满或已赢得,下一个人可以选择进入哪个网格

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

TTT板工具板 终极TTTBoard扩展TTTBoard工具板 TTTBoard.move抛出位置takenexception UltimateTTBoard.move引发LocationTakeNexException,TargetBoardFullException 请注意,在标准tic tac toe中,只有一块板,因此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.
    }
}

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

LSB背后的推理是单词替换,因此如果B做的某些事情完全不同,需要更多的代码才能像try/catch块一样处理它,那么,如果不进一步重构,就不能用C替换/替换它。所以B可以做不同的事情,但不应该破坏A定义的规则。B应该捕获异常C并将其转换为某种允许A抛出的异常,可能是通过包装它。或者更好的是,B的异常可以是A的异常的子类。如果我给出确切的情况,也许会更容易理解。我现在将更新问题。move做什么?这是一个球员的举动吗?如果是的话,那么这真的应该处理到另一个板的切换吗?这是否仍然符合?在接口上,A不是接口。我理解代码在做什么。我只是很难理解为什么你想做A=新的B。另外,我应该怎么做?我已经根据具体情况更新了这个问题。@DuncanX.Simpson为什么要做A=new B->是,但A不是接口。B建立在A的基础上,但做了一些不同的事情。