协变返回的基本用法是用于在已知一个实现的返回类型比API更具体的时候避免进行类型强制转换(一般是子类比其父类更具体)。在下面这个例子中,有一个返回Animal
对象的Zoo接口。我们的实现返回一个AnimalImpl
对象,但是在JDK 1.5之前,要返回一个Animal
对象就必须声明。
复制内容到剪贴板
代码:
public interface Zoo {
public Animal getAnimal();
}
public class ZooImpl implements Zoo {
public Animal getAnimal(){
return new AnimalImpl();
}
}(AnimalImpl是Animal的子类)
协变返回的使用替换了三个反模式:
第一种形式,直接字段访问。为了规避API限制,一些实现把子类直接暴露为字段:
复制内容到剪贴板
代码:
ZooImpl._animal另一种形式是,在知道实现的实际上是特定的子类的情况下,在调用
程序中执行向下转换:
复制内容到剪贴板
代码:
((AnimalImpl)ZooImpl.getAnimal()).implMethod(); //implMethod()为AnimalImpl类的方法我看到的最后一种形式是一个具体的方法,该方法用来避免由一个完全不同的签名所引发的问题:
复制内容到剪贴板
代码:
ZooImpl._getAnimal();以上三种模式都有它们的问题和局限性。要么是不够整洁,要么就是暴露了不必要的实现细节。
协变返回模式就比较整洁、安全并且易于维护,它也不需要类型强制转换或特定的方法或字段:
复制内容到剪贴板
代码:
public AnimalImpl getAnimal(){
return new AnimalImpl();
} 使用结果:
复制内容到剪贴板
代码:
ZooImpl.getAnimal().implMethod();从上可以看出,可以在已知继承关系的情况下,使用其子类的返回类型来“重载”其接口实现或者父类方法。此方法就是——协变返回