在 Java 中重写方法时会发生什么?

What happens when a method is overridden in Java?

当 Java 中的预定义方法被覆盖时...

  1. 只有方法签名必须相同
  2. 方法签名和继承必须相同

答案是什么? 1 或 2

我知道当我们覆盖超类中的方法时,方法签名应该是相同的。但是遗产呢?我在书上看过这个问题,但经过一番研究也没有找到任何答案。

From the docs:

An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.

方法签名必须相同;即名称、参数、参数位置、参数个数必须匹配。

最常见的例子是 toString(),它存在于 ObjectObjecttoString 方法定义如下:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

...而 AbstractCollection* 的 toString 方法定义为:

public String toString() {
    Iterator<E> it = iterator();
    if (! it.hasNext())
        return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = it.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! it.hasNext())
            return sb.append(']').toString();
        sb.append(',').append(' ');
    }
}

注意这两个方法签名是相同的,但是它们 return 是不同的。这是覆盖的意图;你的 parent class 已经为它定义了在 children classes 中不一定有意义的特定行为,所以一个人简单地超越了那个行为并使其适合child class.

*:这用于任何 AbstractCollection,例如 ArrayListLinkedList.


扩展一下:child中方法的可见性也有影响。

从此handy chart,具有private修饰符的方法无法传递给subclasses。

覆盖方法时,不能降低方法的可见性;也就是说,您不能按照提供的可见性顺序降低。

为了提供帮助,这里有一个快速列表。

如果您 parent 中的方法是...

  • public: subclass' override must be public.
  • protected:subclass' 覆盖可以是 publicprotected.
  • <no modifier> 或 package-private:subclass' 覆盖可以是 publicprotected 或 package-private.
  • private: 子class甚至不知道方法存在.