在子类

时间:2015-08-10 22:10:26

标签: java

最近我使用main方法使用一些简单的Java代码来快速测试我编写的代码。我最终遇到了两个类似的类:

public class A {
    public static void main(String[] args) {
        // code here
    }
}



public class B extends A {
    public static void main(String[] args) throws IOException {
        // code here
    }
}

我很惊讶代码停止编译,Eclipse抱怨Exception IOException is not compatible with throws clause in A.main(String[])

嗯,这两种方法都是静态的,而main中的B函数只是隐藏A中的一个,所以我认为它们之间完全没有关系。在静态方法中,我们没有多态,并且在编译期间调用绑定到具体的方法实现,因此我无法理解为什么main中的B不能抛出未在main中声明的异常A中的签名。

为什么Java设计者决定强制执行这样的约束,如果编译器没有强制执行约束,它会在什么情况下导致问题?

3 个答案:

答案 0 :(得分:2)

我从来没有意识到这个事实,但在准确分析之后,我认为没有理由为什么编译器应该强制执行这样的约束。尽管如此,匹配main方法时不会出现不一致,因为静态方法的链接也是静态的。在这种情况下,不允许覆盖。

答案 1 :(得分:1)

关键是我们正在讨论静态方法,它们确实不应受多态性的影响。但是,在我看来静态方法属于一个Class对象,就像任何其他对象应该服从多态,对吗?

答案 2 :(得分:-3)

'extends'关键字表示在声明B类时继承A类中的方法。由于A类是B类的父类,所以主方法的声明仍然在A类中,尽管你是正在B类重新定义它。

当您处理静态方法时,父类方法不会被子类覆盖,只是隐藏它。

http://docs.oracle.com/javase/tutorial/java/IandI/override.html

可以提供更多细节,但这里有一段摘录:

  

隐藏静态方法和覆盖实例方法之间的区别具有重要意义:

     

被调用的重写实例方法的版本是   一个在子类中。得到的隐藏静态方法的版本   调用取决于它是从超类调用还是调用   子类。

原始答案

编译器强制使用此约束来帮助简化更复杂层次结构中的继承。

以toString()方法为例。它由Java中的每个对象继承,假设您能够覆盖此方法的声明以允许子类抛出不同的异常。在处理所有这些潜在的新例外方面,这是一个灾难的处方。

TLDR-编译器强制您遵守父类函数定义,以便其他程序员可以在晚上睡觉。

相关问题