【问题标题】:Java class questionJava类问题
【发布时间】:2009-04-23 09:27:59
【问题描述】:
class One {
public One foo() { return this; }
}

class Two extends One {
public One foo() { return this; }
}

class Three extends Two {
public Object foo() { return this; }
}

public Object foo() { return this; } 引发编译错误。这是为什么?有人可以解释为什么“对象”类型是不可能的吗? Object 是 Class 一、二的基类吗? If So 为什么会抛出错误?

由于找不到合适的标题,请更改问题的标题。

【问题讨论】:

    标签: java class


    【解决方案1】:

    Three.foo 试图覆盖Two.foo(),但它没有正确执行。假设我要写:

    One f = new Three();
    One other = f.foo();
    

    忽略实际上 Three.foo() 确实返回One这一事实,Three.foo() 的签名并不能保证这一点。因此,对于必须必须返回One的方法来说,它不是一个合适的覆盖。

    请注意,您可以更改返回类型并仍然覆盖,但它必须是 more 特定的,而不是 less。换句话说,这样就可以了:

    class Three extends Two {
        public Three foo() { return this; }
    }
    

    因为ThreeOne 更具体。

    【讨论】:

      【解决方案2】:

      您正在以不受支持的方式更改 foo 方法的签名。多态性仅适用于不同的参数列表,不适用于仅返回类型不同的相同方法。

      如果你想一想,这很自然......如果它起作用并且只知道两个超类之一的人会调用 Three.foo() 他会期望它返回一个(因为是它在 1 和 2 中的工作方式)但在 3 中你实际上可以返回一个 HashMap 并且仍然可以正常运行。

      Jon(在下面的评论中)是正确的,您可以缩小范围,但您仍然会遵循将返回“一”的协议(如果您从 Three.foo() 返回一个三),因为子类将都实现了超类接口。 但是,返回类型仍然不是多态性的一部分,因此您不能拥有三种仅因返回类型不同而不同的方法。

      【讨论】:

      • 不正确。您可以通过使返回类型 more 具体化来覆盖。
      • 我正要在编辑中这么说,但你两个对我来说很快:-)
      【解决方案3】:

      它将启用:

      class Four extends Three {
      public Object foo() { return "This String is not an instance of One"; }
      }
      

      【讨论】:

        【解决方案4】:

        重写一个方法并试图返回一个不太具体的类型违反了Liskov substitution principle,它规定子类必须履行其超类的所有契约。您的第三类违反了超类合同“foo() 返回 One 的实例”。

        【讨论】:

          猜你喜欢
          • 2015-01-07
          • 1970-01-01
          • 1970-01-01
          • 2013-01-25
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 2010-09-24
          相关资源
          最近更新 更多