如何将子类实例分配给通用对象(扩展父对象)?

时间:2019-02-08 15:01:34

标签: java generics inheritance

我有一个这样定义的父类:

public abstract MyParent {

    public static <MP extends MyParent> MP getInstance(Object... params) {
        return new MyChild(params);
    }
}

其中MyChild扩展了MyParent。问题是编译器不会让我返回新的子级,因为“ MyChild无法转换为MP”。如果我在返回(return (MP) new MyChild(params);)之前进行投射,则会收到未经检查的投射警告。

正确的方法是什么?

2 个答案:

答案 0 :(得分:0)

MP可以是扩展MyParent的任何东西,但是MyChild不会成为MyParent的每个子类的子类。

我认为您的目的是让getInstance返回MyParent的实例,而不是使其返回通用MP。

答案 1 :(得分:0)

自从你

  

具有[三个] MyChilds,并且[]根据参数获得一个不同的Child

您面临一个基本挑战:方法的调用者如何知道期望的返回类型,并且编译器如何事先知道实际返回的对象的类型与调用者期望的类型兼容?编译时类型的安全性绝对取决于后一种分析,没有这种分析,您想象中为避免强制转换而进行的任何操作都是令人困惑的。

尚不清楚方法参数与结果类型之间的具体关系,但是如果它取决于参数类型之外的任何其他条件,那么您就可以完成。在这种情况下,就无法避免在某处进行强制转换或等效转换。然后,您更好的选择包括

  • 让方法返回MyParent,并接受如果调用程序依赖于特定的子类型,则调用者将需要强制转换结果。

  • 为每种实际的返回类型创建一个不同的名称的方法。这样可以避免调用程序进行强制转换,但是如果给定的参数与所调用方法的类型不正确,则可能要求提供例外。

当然,您也可以修改方法,以使返回类型 基于参数的类型。例如,您可能

  • 在方法参数中包括type-token。但是,要使其用作强制转换等效项,该方法需要以某种方式将类型令牌与其他参数相关联,或使用它来真正选择返回类型,或将返回值强制为指定的类型。