【问题标题】:Polymorphism Object String多态对象字符串
【发布时间】:2018-12-18 20:42:08
【问题描述】:

我没有理解多态性。

举个例子:

Object o = new String ("foo");

我做不到

o.substring (1,2)

谁能给我解释一下这个问题?

【问题讨论】:

  • 因为变量o的类型是Object,它没有调用substring的方法。该变量可能引用不同类型的内存中对象,但变量本身预计类型为Object,仅此而已。例如,如果您知道某事物是 Car,但您不知道 Car种类 是什么,则不能保证您可以与该 @ 上的特定选项进行交互987654329@ 因为它可能没有这些选项。

标签: java polymorphism


【解决方案1】:

这是Liskov Substitution Principle 的结果,它指出(总结):

如果 S 和 T 是对象,并且 T 是 S 的 子类型,则可以在需要 S 的地方使用 T。

String is-aObject 的子类型,因此如果您的赋值操作需要Object,那么它将很乐意接受Object 或其任何子类型。

(注意:Object不是String。所有Strings 都是Objects,但并非所有Objects 都是Strings。)

这并不意味着您可以访问子类型的任何方法。鉴于继承层次结构,Object 不知道它的任何子代的特定方法,也不能 - 无法告知祖先类其后代的能力。因为Object 没有与之关联的substring 方法,所以您的代码正确导致编译失败。

(它应该是,因为Object所有类的祖先。不能保证任何给定的ObjectString。)

常规建议是不要使用过度不特定的对象类型(随着层次结构链的上升,功能变得不那么具体 - 当你上升到 Object 时,你会失去功能)来完成特定于更具体类型的事情。

【讨论】:

    【解决方案2】:

    您将dynamic and static typingpolymorphism 混淆了。

    Java 是一种静态类型语言,因此编译器识别出Object 没有substring() 方法并引发错误。多态性发生在编译之后,代码实际执行时。

    【讨论】:

      【解决方案3】:

      第一件事不是多态。

      以简单的方式,在您的情况下,o 对象将仅调用在 Object 类中定义的方法。如果String 类重写了Object 类的任何方法,那么对象o 将执行String 类的方法,否则对象o 将调用它自己的方法。

      例如:

      substring() 方法仅在 String 类中定义 所以在这种情况下,您的代码将抛出异常,但是如果您调用 equals()hashcode()toString() 方法(因为这些方法在 Object 中定义class ) 然后 String class 中的定义将被执行,因为 String Class 已经覆盖了这些方法。如果 object Class 中的任何方法没有在其子类中被覆盖,则 Object 类中的定义将被执行。

      【讨论】:

        【解决方案4】:

        substring 来自 String 类,而不是 Object 类。所以下面的代码可以工作:

        String o = new String ("foo");
        o.substring(1,2);
        

        此代码不起作用:

        Object o = new String ("foo");
        o.substring(1,2);
        

        由于String继承自Object,所以String可以调用Object的方法,如toString。但是Object不继承自String,所以Object不能调用String的方法,比如substring

        【讨论】:

          猜你喜欢
          • 2022-06-10
          • 1970-01-01
          • 1970-01-01
          • 2019-03-20
          • 2014-02-02
          • 2012-10-11
          • 2020-06-09
          • 2019-12-29
          • 2015-08-29
          相关资源
          最近更新 更多