Java 我如何概括这一点?

Java 我如何概括这一点?,java,generalization,Java,Generalization,我有一个类ExampleProperty,它扩展了超类Property,在一个单独的类GameObject中,我有一个arraylistproperties以及下面的方法,其中Engine.createEngineObject(new ExampleProperty())只添加new ExampleProperty()返回列表,propertyId是属性的继承成员,其中属性是属性的列表: public ExampleProperty addExampleProperty() {

我有一个类
ExampleProperty
,它扩展了超类
Property
,在一个单独的类
GameObject
中,我有一个
arraylistproperties
以及下面的方法,其中
Engine.createEngineObject(new ExampleProperty())
只添加
new ExampleProperty()
返回列表,
propertyId
属性
的继承成员,其中
属性
属性
的列表:

public ExampleProperty addExampleProperty()
    {
        ExampleProperty temp = (ExampleProperty)Engine.createEngineObject(new ExampleProperty());
        temp.propertyId = properties.size();
        return temp;
    }
我想推广这个方法,这样我就可以传入一个
类propertyClass
,让它返回一个与
propertyClass
类型相同的对象(还可以在第3行执行强制转换?)。恐怕我对泛化还不够熟悉,所以非常感谢您的帮助:)

编辑:这是答案发布后的修订代码。我忘了提一点信息,但我已经处理过了,所以这里是我所拥有的。这可能很糟糕,但它是我的,它有效,我为此感到自豪:

public <T extends Property> T addProperty(Class<T> propertyClass) throws IllegalAccessException, InstantiationException {
        Property property = propertyClass.newInstance();
        if(propertyClass.getSuperclass() == Engine.class)
        {
            Engine temp = Engine.createEngineObject(propertyClass.newInstance());
            temp.propertyId = properties.size();
            return (T)temp;
        }
        T temp = propertyClass.newInstance();
        temp.propertyId = properties.size();
        return (T)temp;
    }
public T addProperty(类propertyClass)抛出IllegaccessException、InstanceionException{
Property=propertyClass.newInstance();
if(propertyClass.getSuperclass()==引擎类)
{
Engine temp=Engine.createEngineObject(propertyClass.newInstance());
temp.propertyId=properties.size();
返回(T)温度;
}
T temp=propertyClass.newInstance();
temp.propertyId=properties.size();
返回(T)温度;
}

这可能会起到以下作用:

public T createEngineObject(类propertyClass)抛出IllegaAccessException、InstanceionException{
Property=propertyClass.newInstance();
//做点什么。。。
归还财产;
}
尽管如此,传递
属性
实例似乎是一个更好的主意:

公共T createEngineObject(T属性){ //做点什么。。。 归还财产; }
这里的中心问题是,您对
ExampleProperty
所做的事情没有捕获到类型中。因此,你不能一字不差地概括这一点

让我们列出您对当前硬编码类型(ExampleProperty)的“操作”,以便我们知道在类型中捕获什么,从而可以对其进行概括:

  • 调用它的无参数构造函数
  • 将该结果作为调用
    Engine.createEngineObject
    的第一个参数传递
  • createEngineObject
    调用的结果强制转换到此类型
  • 您可以引用此类型的
    propertyId
    字段
  • 返回类型
在所有这些操作中,最有问题的是第一个操作:构造函数不参与键入系统。不能在java类型中声明“没有参数构造函数”。完全无论如何

有两种解决方案:

  • 只在文档中声明,编译时保证为零,并使用
    java.lang.Class
    实例作为工具,以便代码知道从何处获取构造函数。编译时不会检查传递到该方法的泛型形式中的任何类型实际上是否具有无参数构造函数,或者它是否是非抽象的。如果您失败了这些条件,您将知道的唯一方法是在运行时会发生一些异常
  • 使用工厂
  • 正确答案当然是第二个:使用工厂。捕获“可以生成ExampleProperty实例的东西”的概念,因为可以在java的类型系统中传递。如果出现以下情况,我们可以将该工厂用作适用于整个车型的任何车辆:

    您的通用代码:

    public interface PropertyFactory<P extends Property> {
        P make();
    }
    // NB: You can replace the above with `java.util.function.Supplier` instead, but I'd make your own type.
    
    public abstract class Property {
        int propertyId;
    }
    
    public <P extends Property> P addProperty(PropertyFactory<P> factory) {
        P temp = Engine.createEngineObject(factory.make());
        temp.propertyId = properties.size();
        return temp;
    }
    
    // in Engine.java
    public <P extends Property> P createEngineObject(P property) {
        // do stuff here
        return property;
    }
    
    
    公共接口属性工厂{
    P make();
    }
    //注意:您可以用'java.util.function.Supplier'替换上面的内容,但我会自己创建类型。
    公共抽象类属性{
    int-propertyId;
    }
    public

    P addProperty(PropertyFactory

    factory){ P temp=Engine.createEngineObject(factory.make()); temp.propertyId=properties.size(); 返回温度; } //在Engine.java中 public

    P createEngineObject(P Property){ //在这里做事 归还财产; }

    然后使用:

    private static final PropertyFactory<ExampleProperty> EXAMPLE_MAKER = ExampleProperty::new;
    
    ExampleProperty ep = addProperty(EXAMPLE_MAKER);
    
    私有静态最终属性工厂示例\u MAKER=ExampleProperty::new;
    ExampleProperty ep=addProperty(EXAMPLE_MAKER);
    
    Dude做这件事让我觉得自己脑子太大了,但经过一点调整后,你的解决方案100%有效。谢谢你,bunchSee我对你用来写更新的答案的评论-不幸的是,这是一个错误的答案。