Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.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 - Fatal编程技术网

Java泛型、接口和类继承

Java泛型、接口和类继承,java,generics,Java,Generics,以抽象类为例: public abstract class Animal { ...} 以及界面: public interface Canine<T extends Animal> {...} (注意:选项取自vavr库) 此存储库用于以下类别: public abstract AbstractFinderClass<T extends Animal & Canine<T>> { private Class<T> anima

以抽象类为例:

public abstract class Animal { ...}
以及界面:

public interface Canine<T extends Animal> {...}
(注意:
选项
取自
vavr
库)

此存储库用于以下类别:

public abstract AbstractFinderClass<T extends Animal & Canine<T>> {

    private Class<T> animalType;

    public AbstractFinderClass(Class<T> animalType) {
        this.animalType = animalType;
    }

    public Option<T> findMyAnimal(String id) {
        return repository.findById(id, this.animalType);
    }
}
公共抽象AbstractFinderClass{
私有类动物型;
公共AbstractFinderClass(类animalType){
this.animalType=animalType;
}
公共选项findMyAnimal(字符串id){
返回repository.findById(id,this.animalType);
}
}
然后以具体形式实施,包括:

public class DogFinder extends AbstractFinderClass<Dog> {
    public DogFinder() {
        super(Dog.class);
    }
}
公共类DogFinder扩展了AbstractFinderClass{
公共寻狗器(){
超级(狗类);
}
}
现在,行
return repository.findById(id,this.animalType)
导致两个错误:

  • 在第二个参数上,
    this.animalType
    的类型为
    Class
    ,而预期的类型为
    Class
    ,并且这些类型显然不兼容
  • 返回类型应该是
    Option
    ,而我得到的是
    Option
  • 恐怕我遗漏了一些“小”细节,因为我希望
    Dog
    T
    能够兼容。
    您能帮我解决这个问题吗?

    第一个问题是您有一个不必要的类型参数用于
    DogFinder
    。它是一个dog finder,因此它所查找的内容的类型参数是多余的(非常规命名的类型参数
    dog
    可能表明存在问题)。应该是:

    class DogFinder extends AbstractFinderClass<Dog> {
        public DogFinder() {
            super(Dog.class);
        }
    }
    
    第三,除非我们缺少上下文,否则我相信您的
    犬科
    类型不需要是泛型的(除非事情必须复杂):

    如果您需要一个专门的犬类查找器,只需更改存储库类,如下所示:

    abstract class CanineFinderClass<T extends Animal & Canine>
        implements Repository<T> {...}
    

    我想知道
    存储库
    类应该如何实现。
    findById
    方法不应该具有相同类型的擦除吗?您可以不在repository类中重载相同的方法,而将其转换为单个泛型方法吗?基本上
    选项findById(字符串id,类类型)。我认为您会遇到错误,因为
    T
    可能是
    存储库中未定义的类型,因此您会尝试执行不存在的方法。如果
    DogFinder
    应该是
    AbstractFinderClass
    的具体实现,为什么它没有
    extends
    子句?我们无法确定您的
    t
    是否为
    Dog
    。事实上,为什么它甚至有
    Dog
    作为通用参数?这会造成与
    Dog
    类的混淆。你的代码实际上不会编译。我建议一个。您需要的基本上是Bloch的“类型安全异构容器”实现——您应该查看详细描述此方法的有效Java。在这种特殊情况下,您可能会发现它很有用。类型参数应该从类存储库移到findById方法中,因为存储库可以处理所有动物类型。@AlexeiKaigorodov想法是给定的存储库可以处理任何动物类型,而不是所有动物类型。因此,在实例化时,type参数将定义哪种动物类型。因此,当重用repo时,您会得到相同的类型(否则,每次方法调用时都必须传入
    animalType
    参数)。主题启动程序的思想是存储库可以处理所有类型,而AbstractFinderClass可以处理任何类型。否则,就不需要两个不同的类,每个类都处理一些具体的动物类型。@AlexeiKaigorodov这正是我旁注的重点(我怀疑我们说的是同一件事)。给定的类型可以与任何动物类型一起工作(因此类型本身是泛型的),但是当创建存储库的实例时,它会绑定到一个具体的动物类型(因此方法不是泛型的)。OP最大的问题是
    DogFinder
    上的(可能是偶然的)类型参数在
    DogFinder
    上的额外参数上有问题,抱歉:我错误地删除了一段代码:/参见更新的问题。
    class DogFinder extends AbstractFinderClass<Dog> {
        public DogFinder() {
            super(Dog.class);
        }
    }
    
    interface Repository<T extends Animal> {
        Option<T> findById(String id, Class<T> type);
    }
    
    interface Canine {
    }
    
    abstract class CanineFinderClass<T extends Animal & Canine>
        implements Repository<T> {...}
    
    class AnimalFinderClass<T extends Animal> implements Repository<T> {
    
        Repository<T> repository;
    
        private Class<T> animalType;
    
    
        public AbstractFinderClass(Class<T> animalType) {
            this.animalType = animalType;
        }
    
        public Option<T> findMyAnimal(String id) {
            return repository.findById(id, this.animalType);
        }
    }