Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用不同的泛型类型在继承层次结构中实现两次泛型接口_Java_Generics_Inheritance - Fatal编程技术网

Java 使用不同的泛型类型在继承层次结构中实现两次泛型接口

Java 使用不同的泛型类型在继承层次结构中实现两次泛型接口,java,generics,inheritance,Java,Generics,Inheritance,我用Java创建了一个通用接口,以便以类型安全的方式表示某个对象的ID。基本上是这样的: public interface ID<T extends BaseOfAllIDNeedingObjects> { long getId(); boolean isConcrete(); } 当然,我希望能够在不同的情况下表示基本事物和特定事物的ID。获取一个特定的东西需要额外的工作才能从数据库中的不同表中提取数据,所以有时候我只需要一个BaseThing,因为它包含了我当时

我用Java创建了一个通用接口,以便以类型安全的方式表示某个对象的ID。基本上是这样的:

public interface ID<T extends BaseOfAllIDNeedingObjects> {
    long getId();
    boolean isConcrete();
}
当然,我希望能够在不同的情况下表示基本事物和特定事物的ID。获取一个特定的东西需要额外的工作才能从数据库中的不同表中提取数据,所以有时候我只需要一个BaseThing,因为它包含了我当时需要的所有信息。但是,Java不允许以下情况:

public class BaseThing extends BaseOfAllIDNeedingObjects implements ID<BaseThing> {
    /* base thing stuff here */
}

public class SpecificThing extends BaseThing implements ID<SpecificThing> {
    /* specific things */
}
公共类BaseThing扩展了BaseofAllidNeedingObject实现ID{
/*卑鄙的东西*/
}
公共类SpecificThing扩展BaseThing实现ID{
/*具体的事情*/
}

这是一个直接的编译器错误。我的IDE(Jetbrains)说“ID不能用不同的类型参数'BaseThing'和'SpecificThing'继承”。有什么办法可以解决这个问题吗?我是否只需要不使用ID标记BaseThing,只允许使用SpecificThings作为ID,将BaseThing包装在单独的ID对象中?或者,是否有一些我不知道的模式允许我在工作中欺骗类似的东西?

您可以将
BaseThing
的实现向上拉到一个抽象类,然后使用一个自递归泛型参数:

public abstract class AbstractBaseThing<T extends AbstractBaseThing<T>> extends BaseOfAllIDNeedingObjects implements ID<T> {
    /* base thing stuff here */
}

public class BaseThing extends AbstractBaseThing<BaseThing> {
    /* concrete base thing */
}

public class SpecificThing extends AbstractBaseThing<SpecificThing> {
    /* specific things */
}
公共抽象类AbstractBaseThing扩展了BaseofAllidNeedingObject实现ID{
/*卑鄙的东西*/
}
公共类BaseThing扩展了AbstractBaseThing{
/*混凝土底座*/
}
公共类SpecificThing扩展了AbstractBaseThing{
/*具体的事情*/
}

您可以这样定义类:

public class BaseThingGeneric<T extends BaseThingGeneric<T>> extends BaseOfAllIDNeedingObjects implements ID<T> {
    /* base thing stuff here */
}

public class BaseThing extends BaseThingGeneric<BaseThing> {
    /* just redefine the constructors */
}

public class SpecificThingGeneric<T extends SpecificThingGeneric<T>> extends BaseThingGeneric<T> {
    /* specific things */
}

public class SpecificThing extends SpecificThingGeneric<SpecificThing> {
    /* just redefine the constructors */
}
公共类BaseThingGeneric扩展了BaseOfAllidNeedingObject实现ID{
/*卑鄙的东西*/
}
公共类BaseThing扩展了BaseThingGeneric{
/*只需重新定义构造函数*/
}
公共类SpecificThingGeneric扩展了BaseThingGeneric{
/*具体的事情*/
}
公共类SpecificThing扩展SpecificThingGeneric{
/*只需重新定义构造函数*/
}
实现将采用BaseThingGeneric和SpecificThingGeneric。 提供BaseThing和SpecificThing只是为了简化实例化。
此外,通过扩展SpecificThingGeneric,ScecificThing也将以同样的方式进行扩展。

基本上:当前代码库传递大量表示不同对象的“长someId”参数,例如BaseThing、SpecificThing或其他一些完全不相关的对象。我希望使这些参数类型安全、自文档化(不仅仅是“类型名称+id”),并允许传递对象的具体实例,而不是在长时间内保存一些内存分配的包装器。编辑:在很多情况下,我们不希望将对象拉入内存,而只需要ID,因为long将直接传递给SQL。
public class BaseThingGeneric<T extends BaseThingGeneric<T>> extends BaseOfAllIDNeedingObjects implements ID<T> {
    /* base thing stuff here */
}

public class BaseThing extends BaseThingGeneric<BaseThing> {
    /* just redefine the constructors */
}

public class SpecificThingGeneric<T extends SpecificThingGeneric<T>> extends BaseThingGeneric<T> {
    /* specific things */
}

public class SpecificThing extends SpecificThingGeneric<SpecificThing> {
    /* just redefine the constructors */
}