简体   繁体   English

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

[英]How to assign child class instance to generic (extends parent) object?

I have a parent class defined like this: 我有一个这样定义的父类:

public abstract MyParent {

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

where MyChild extends MyParent . MyChild扩展MyParent The problem is the compiler wont let me return the new child because " MyChild cannot be converted to MP ". 问题是编译器不会让我返回新的孩子,因为“ MyChild无法转换为MP ”。 If I cast before return ( return (MP) new MyChild(params); ) I get an unchecked cast warning. 如果我在return之前return (MP) new MyChild(params);return (MP) new MyChild(params); ), return (MP) new MyChild(params);收到未经检查的强制转换警告。

What is the correct way to do this? 正确的方法是什么?

MP can be anything that extends MyParent, but MyChild is not going to be a subclass of every subclass of MyParent. MP可以是扩展MyParent的任何东西,但是MyChild不会成为MyParent的每个子类的子类。

I think your intention here is to have getInstance return an instance of MyParent instead of having it return a generic MP. 我认为您的意图是让getInstance返回MyParent的实例,而不是使其返回通用MP。

Since you 自从你

have [three] MyChilds, and [] get a diferent Child according to the parameters 有[三个] MyChilds,并且[]根据参数获得一个不同的Child

you have a fundamental challenge: how does the invoker of your method know which return type to expect, and how can the compiler know in advance that the type of the object actually being returned is compatible with the type the invoker expects? 您面临一个基本挑战:方法的调用者如何知道期望的返回类型,并且编译器如何事先知道实际返回的对象的类型与调用者期望的类型兼容? Compile-time type safety absolutely depends on the latter analysis, and without that, anything you imagine doing to avoid casts is just obfuscatory. 编译时类型的安全性绝对取决于后一种分析,没有这种分析,您想像中为避免强制转换而进行的任何操作都是混淆性的。

The specific relationship between your method parameters and result type is unclear, but if it depends on anything beyond the types of the parameters, then you're done. 方法参数与结果类型之间的具体关系尚不清楚,但是如果它取决于参数类型之外的任何其他条件,那么您就可以完成。 In that case there is no avoiding a cast or cast-equivalent somewhere. 在这种情况下,就无法避免在某处进行强制转换或等效转换。 Your better options then include 然后,您更好的选择包括

  • have the method return MyParent , and accept that the invoker will need to cast the result if it depends on the specific subtype (but not otherwise). 让方法返回MyParent ,并接受如果调用程序依赖于特定的子类型,则调用者将需要MyParent结果(但不是)。

  • create a different and differently-named method for each actual return type. 为每种实际的返回类型创建一个不同的名称的方法。 This will avoid the need for the invoker to cast, but it may require provision for an exception in the event that the given parameters do not correspond to an object of the correct type for the method called. 这样可以避免调用程序进行强制转换,但是如果给定的参数不对应于所调用方法的正确类型的对象,则可能需要提供例外。

Of course, you may also be able to modify the method so that the return type is based on the types of the parameters. 当然,你也能够修改方法,以便返回类型基于类型的参数。 For example, you might 例如,您可能

  • include a type-token among the method paramerers. 在方法参数中包括类型标记 For this to serve as other than a cast equivalent, however, the method needs somehow to associate the type token with the other parameters, or to use it to genuinely select the return type, or coerce the return value to the specified type. 但是,要使其用作强制转换等效项,该方法需要以某种方式将类型标记与其他参数关联,或使用它来真正选择返回类型,或将返回值强制为指定的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM