具有协变返回类型的Java类型转换

具有协变返回类型的Java类型转换,java,inheritance,Java,Inheritance,我为协变返回类型的继承创建了一个小示例。基本上有三个不同的类别: 主应用程序: public class MainApp { public static void main(String[] args) { BaseManager manager = new BirdManager(); BirdManager birds = (BirdManager) manager.getManager(); // <-- Why type cast here // prints Bi

我为协变返回类型的继承创建了一个小示例。基本上有三个不同的类别:

主应用程序:

public class MainApp {
  public static void main(String[] args) {
  BaseManager manager = new BirdManager();
  BirdManager birds = (BirdManager) manager.getManager(); // <-- Why type cast here
  // prints BirdManager
  }
}
当我重写方法e
getManager()
以返回
BirdManager
时,为什么需要将
BaseManager
键入
BirdManager

我用过作参考

编辑:


我有不同的子模型,它们都继承自
BaseManager
。所有模型只允许存在一次。我没有为每个模型使用单例,而是尝试将这些模型添加到列表中。使用
getManager()
我想要得到实际的模型。也许我必须过度思考我的设计。

您正在调用方法的
管理器
对象是
基本管理器
,而不是
鸟类管理器
。编译器不知道您实际上正在调用
BirdManager
的一个方法,它只会在运行时被知道,这就是为什么您需要一个cast。

您调用方法的
manager
对象是
BaseManager
,而不是
BirdManager
。编译器不知道您实际上正在调用
BirdManager
的方法,它只会在运行时被知道,这就是为什么您需要强制转换的原因。

因为manager是BaseManager的实例,而不是BirdManager。为了使您可以将其用于birds实例,您需要对其进行类型转换。

因为manager是BaseManager的实例,而不是BirdManager。因此,您可以将其用于birds实例,您需要对其进行类型转换。

这是因为
manager
属于
BaseManager
类型,因此编译器只“知道”
manager.getManager()
返回
BaseManager
BaseManager.getManager()的签名确认。为什么还需要
getManager()
方法?这是因为
manager
属于
BaseManager
类型,因此编译器只“知道”
manager.getManager()
返回
BaseManager
BaseManager.getManager()的签名确认。你为什么还需要
getManager()
方法呢?好的,这是有道理的。有没有办法避免使用特定模式或泛型进行类型转换?或者在这种情况下,类型转换是否“足够好”?我真的不明白
getManager()
方法的意义,但在
BaseManager
类中可能类似这样:
public t getManager(){return(t)this;}
。我不建议使用它,它只是一种可能性,它破坏了泛型的全部用途(编译时类型安全)。好的,这是有意义的。有没有办法避免使用特定模式或泛型进行类型转换?或者在这种情况下,类型转换是否“足够好”?我真的不明白
getManager()
方法的意义,但在
BaseManager
类中可能类似这样:
public t getManager(){return(t)this;}
。我不建议使用它,它只是一种可能性,它破坏了泛型的全部用途(编译时类型安全)。
public abstract class BaseManager {
  private Map<ManagerType, BaseManager> list = new EnumMap<>(ManagerType.class);
  protected Map<ManagerType, BaseManager> getList() {
    return list;
  }
  public abstract BaseManager getManager();
}
public class BirdManager extends BaseManager {
  public BirdManager getManager() {
    if (!super.getList().containsKey(ManagerType.BIRD)) {
        super.getList().put(ManagerType.BIRD, this);
    }
    return (BirdManager) super.getList().get(ManagerType.BIRD);
}