协变返回类型允许子类重写方法时返回更具体的子类型,既符合里氏替换原则又避免强制转型;要求父类返回引用类型、子类返回其子类,且方法签名一致,Java 5起支持。
这是Java多态机制中一个关键但容易误解的细节:子类重写父类方法时,返回值类型可以是父类返回值类型的子类——这叫协变返回类型(Covariant Return Type),从Java 5开始支持,Java 7及以后已全面稳定使用。
核心是为了增强类型安全性与表达力,同时不破坏多态原则。父类方法承诺“返回一个A”,子类重写时说“我返回的是更具体的A的子类B”,这完全合理——因为B本身就是A,所有A能做的事,B都能做。
Animal a = dog.getAnimal();)Dog d = dog.getAnimal();),无需强制转型ClassCastException
判断标准只看类继承关系,不看名字或功能是否相似:
Number,子类返回 Integer(Integer 是 Number 的子类)Person,子类返回 Student(Student extends Person)String,子类返回 Integer(无继承关系)Student,子类返回 Person(子类不能返回更宽泛的父类类型)语法上必须显式写出子类类型,并加 @Override 注解(编译器靠它识别这是重写而非重载):
立即学习“Java免费学习笔记(深入)”;
class Animal { public Animal get() { return new Animal(); } }class Dog extends Animal { @Override public Dog get() { return new Dog(); } } // ✅ 正确
如果省略 @Override 或返回类型写错,要么编译失败,要么变成重载(参数相同但返回值不同不是重载,直接报错),不会静默覆盖。
协变返回类型不影响动态绑定逻辑。哪怕你用父类引用调用:
Animal a = new Dog();<br>Animal result = a.get();
Dog.get(),返回的是 Dog 实例——只是被向上转型为 Animal 类型赋给了 result。你可以随时向下转型(但要确保安全),而用子类引用调用则直接拿到 Dog 类型,更自然、更安全。