【问题标题】:How does the compiler identify that the return types of overridden methods are incompatible in Java? [closed]编译器如何识别覆盖方法的返回类型在 Java 中不兼容? [关闭]
【发布时间】:2021-09-21 23:25:07
【问题描述】:

这听起来像是一个重复的问题,但我真的很好奇编译器如何识别被覆盖的方法和覆盖的方法是否具有兼容的类型。正如我们所知,通常使用它们的签名来识别方法,并且签名仅包含方法名称及其参数,因此在重载时可以很容易地确定要选择哪个方法,因此,在重载时我们不能有两个完全相似的方法.但是对于覆盖,我们需要两个方法相同。那么编译器如何识别返回类型是否兼容呢?

编辑。我很清楚要执行的方法是根据程序运行时的引用来选择的,我只是好奇编译器的识别是如何工作的。

【问题讨论】:

  • “我只是对编译器的识别是如何工作的感到好奇。” - 一个好的 CS 专业将包括关于“编译器写作”的(可选)课程。这是一门期末/荣誉学年课程……许多学生跳过它,因为它以困难着称。还有一些关于这个主题的(大)教科书。无论如何......这些将包括关于类型和编译时类型检查的讲座/章节。

标签: java polymorphism overriding


【解决方案1】:

编译器识别重写方法的条件是

  • 方法必须具有相同的签名
  • 方法必须至少与父方法一样可访问
  • 方法必须使用协变返回类型
  • 方法不得声明任何新的或更广泛的异常

如 OCP II 学习指南中所述。

如果方法名称相同但参数列表不同,则方法将被重载。

【讨论】:

    【解决方案2】:

    由于这是一个没有实现Java编译器的社区,我们所能做的就是推测,但无论如何,推测一下,只要客观地完成,可能会成为一本好书。

    所以,我的回答将集中在方法可以如何被验证,因为我不知道编译器实际上是如何完成的。

    首先,一个非常简单的检查是参数个数是否相同。此外,参数的类型和方法的返回类型必须相同才能完全覆盖方法。

    我应该提到,如果您在子类中实现了方法的新签名,那不是问题,这是完全合法的。

    所以,

    class A {
        int foo(long a) { return 0;}
    }
    
    class B extends A {
        int foo(long a) { return 0;}
    }
    
    class C extends A {
        int foo(double a) { return 0;}
    }
    

    完全合法。

    因此,确定一个方法是否是另一个方法的覆盖对于 Java 了解如何应用基于继承的逻辑很重要,但您可以轻松地实现具有不同声明但名称相同的方法。

    【讨论】:

      猜你喜欢
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多