java - 方法隐藏和字段隐藏的继承辅助

标签 java inheritance

public class Test
{
    static int i = 1;

    static void m1()
    {
    }
}

class Test1 extends Test
{
    int i = 1;    //allowed 

    void m1()     // not allowed; Both are instance level, so why this difference? Both can be accessed with super keyword
    {
    }
}

为什么不能用相同的签名隐藏静态方法,而允许静态字段这样做呢?都是实例级的,为什么只允许静态字段?

最佳答案

Test中的

m1()是一个static方法,而中的m1() Test1 是非静态的。现在想象一下,如果允许这样做,那么当您执行以下语句时,运行时将选择哪个实现:

new Test1().m1();

因为子类的实例(在您的情况下为 Test1)也可以访问父类的静态方法(来自 Test)。这就是不允许这样做的原因。

下一个问题为什么在 Test1 中允许使用同名变量:无法从子类实例访问父类的静态变量。换句话说,父类的静态状态对子类是隐藏的。也就是

Test1.i;   // compilation error, can't access parent's static variable

会导致编译错误。如果你尝试

new Test1().i; // will access Test1's i variable

它将指向子类的状态而不是父类的状态。这就是子类可以有同名变量的原因。

注意如果 Test 中的 i 是非静态的,即使在那种情况下 Test1 也可以有名称为 i< 的变量。在这种情况下,Test1 中的 i 将隐藏 Test 中的 i

编辑

来自 Shahaan Syed 的 comment :

new Test1().i; why is this allowed is my concerned

换句话说 Shahaan Syed 的困惑:为什么

  • 在变量的情况下,子类可以有一个非静态变量,同时 父类有一个同名的静态变量,
  • 另一方面,子类不能有非静态方法 父类有同名静态方法?

作为凯文·埃舍 commented ,我还认为 Java 通过允许从子类的实例访问父类的 static 方法搞砸了某个地方。尽管这不是一个好的做法,并且编译器也会生成警告。

这是 ( JLS §8.3 ) 的引述:

In this respect, hiding of fields differs from hiding of methods (§8.4.8.3), for there is no distinction drawn between static and non-static fields in field hiding whereas a distinction is drawn between static and non-static methods in method hiding.

但我在 JLS 中找不到这背后的任何原因。

我认为应该是编译时错误而不是生成警告。即从子类实例访问父类的 static 字段和 static 方法,应该是编译器错误。在这方面,事情本来是一致的,也很容易理解。但这只是我的想法。

同一行的另一个有趣问题:Why isn't calling a static method by way of an instance an error for the Java compiler?

关于java - 方法隐藏和字段隐藏的继承辅助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36642288/

相关文章:

python - 如何在 Python 中实现 'Parameter Object' 重构?

java - 在抽象类中创建方法而不是在扩展它的类中重写它们是一个好习惯吗?

c++ - 在 C++ 中是否有等同于 `instancetype` 的东西?

java - "Fix"Java 中的字符串编码

java - 使用 Google App Engine Java 提供动态图像

java - JSP 模板的任何类型安全替代品

c# - 基类中的派生实例

java - 将我的 C++ 代码转换为 Java : Translating multiple inheritance

java - Activemq Web 管理控制台不工作

java - 为什么执行AudioSystem.getAudioInputStream时出现nullpointerException?