对于方法覆盖,本来我的理解是:子类覆盖父类的方法,当子类的方法签名与父类一致时,算覆盖了父类的方法。然而在研究String相关类源码是发现了这样的代码:
  /**
  * AbstractStringBuilder是StringBuilder和StringBuffer的抽象父类。
  *AbstractStringBuilder类append()方法
  */
  public AbstractStringBuilder append(String str) {
  if (str == null)
  return appendNull();
  int len = str.length();
  ensureCapacityInternal(count + len);
  str.getChars(0, len, value, count);
  count += len;
  return this;
  }
  /**
  * StringBuilder类的append()方法
  */
  @Override
  public StringBuilder append(String str) {
  super.append(str);
  return this;
  }
  猛一看没什么问题,方法名相同,入参一致,子类中还调用的父类的方法,子类确实是覆盖子类了。可是等等,它们的返回值类型居然不一致。
  JDK的代码怎么会有问题,我在本地写了两个类,同样的方式,也可以。然后我猜测,应该是子类的返回类型正好是父类方法返回类型的子类(这个例子的确有点特殊,返回值正好是本身),于是我又做了个实验:
  //创建了两个空类,测试用
  public class Foo {
  }
  class Bar extends Foo{
  }
  /**
  * People作为父类,定义了一个方法
  */
  public class TestPeople {
  Foo  test(Foo f){
  return new Foo();
  }
  }
  public class TestStudent extends TestPeople {
  /**
  * 注意返回值为Bar,父类中返回值为Foo,说明子类返回值类型为父类返回值的子类型也可
  * @param foo
  * @return
  */
  @Override  //强制加覆盖注解为测试是否真正覆盖了父类方法
  Bar test(Foo foo) {
  return new Bar();
  }
  }