【问题标题】:Why Dynamic Method Dispatch is not working on properties?为什么动态方法调度不适用于属性?
【发布时间】:2021-10-02 21:05:59
【问题描述】:
public class Main {
    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.x); // 10 is printed
        System.out.println(p.print()); // Child is printed
    }
}

class Parent{

    int x = 10;
    public String print(){ return "Parent";}
}

class Child extends Parent{

    int x = 55;

    public String print(){ return "Child"; }
}

为什么动态方法调度对属性不起作用? 有什么目的、意义还是就是这样设计的。

【问题讨论】:

  • 为什么“... 方法 ...”不适用于字段。您的问题已经存在明显的矛盾
  • 是的 :) 它是方法调度 :) 好的,为什么没有任何动态属性调度?
  • 老实说,我不知道这其中的技术原因,但这是事实。字段不能那样工作。
  • here 实际上是查看 JLS 的一个不错的答案,但它没有提到 why 部分。
  • 我相信x 不会覆盖父类,它会隐藏它。这似乎是没有区别的区别,但这是我得到的。因为x 没有被覆盖,所以您根据静态类型获得定义,您将其声明为Parent

标签: java inheritance polymorphism overriding dispatch


【解决方案1】:

编写参与继承层次结构的类很困难。我们需要类公开行为并允许子类进行自定义,但不允许子类改变超类所依赖的东西。允许子类覆盖方法,但保持超类状态为私有来实现这种分离。

但是,如果子类可以覆盖超类中的变量,那么超类就无法对其需要操作的变量有信心,并且子类可以篡改超类。超类可以工作也可以不工作,这取决于它的扩展。

如果这是一个特性,并且您可以选择是否使用它,类似于在 C# 中使用诸如 virtual 之类的关键字,但对于方法,您什么时候使用它?我想不出一个有意义的案例。

【讨论】:

    【解决方案2】:

    有效吗?因为与方法不同,字段不能被覆盖。从根本上说:这毫无意义。

    当您覆盖一个方法时,不仅仅是名称。只有当 一切 匹配时,它才算数。让我们试试这个:

    public class Example {
        @Override public boolean equals(Example other) { return false; }
    }
    

    上面的不会编译,因为那与Object自己的equals相同。参数类型不匹配。作为对您的语言语法糖精,您可以“扩展”您的规范(您可以指定更具体的返回类型和更通用的参数类型,并且您可以选择声明更少的检查异常),但是如果您检查一个类文件中,您会在自己的父类中找到exact方法签名。

    将该概念扩展到字段,字段不仅仅是的名称。这是名称​​及其类型

    当您在class Parent 中声明int x; 时,该字段存在于Parent 的所有实例中,包括Parent 子类的任何实例。换句话说,您的 class Child extends Parent已经有一个 x 字段。你无法改变它的本质。这与方法形成鲜明对比,您可以通过更改代码重新定义它的功能。这只是不适用于字段:字段没有代码。

    正因为如此,当您声明一个与父方法声明具有相同签名的方法时,这就是一个覆盖,但是:

    当您声明一个与父类的字段具有相同签名(相同名称、相同类型)的字段时,您是在声明第二个单独的字段,其名称会影响父类的字段

    行为完全不同。简单的解决方案是根本不声明int x,在孩子。如果必须的话,写到父母的x。以上解释了为什么这种行为如此不同。

    【讨论】:

      猜你喜欢
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 2022-08-07
      • 2016-01-25
      • 2020-05-24
      相关资源
      最近更新 更多